dart 01变量、常量、类型

变量

变量声明

1. 通过var

  • var name='Bob'
    
  • 变量存储的是对象的引用

    • 变量存储的是对象的引用,这里的变量name存储了一个String类型的引用,Bob则hi这个String类型的引用的值

    • var声明变量后如果没有初始值,可以变成任何类型

    • var a;
      a="name";
      a=123;
      a=true; //这样没有错误编译时根据值来推断类型
      
    • 如果有初始值类型将被锁定,不可改变数据类型

    • var name="Bob";
      name=1000 // 这样是错误的
      
  • name变量的类型被推断为String(Dart支持类型推断)

2.指定类型

可以通过指定类型的方式来改变变量类型,如果对象不确定单个类型可以指定为object或者dynamic

object

  • 动态任意类型类型可变, 编译阶段检查

    • Object object = "hello world";
        print(object.runtimeType); //String
        print(object); //hello world
        object = 1;
        print(object.runtimeType); //int 说明类型是可变的
        print(object); //1
        //object.foo();静态检查会运行报错会报错
        object.foo();
      

dynamic

  • 动态任意类型,编译阶段不检查运行阶段检查

    • dynamic mic = "hello world"; //编译时不会揣测数据类型,但是运行时会推断
      print(mic.runtimeType); //String
      print(mic); //hello world
      //但是这样的坏处就是会让dart的语法检查失效,所以有可能会造成混乱而不报错
      //所以不要直接使用dynamic
      mic.foo();
      //通过它定义的变量会关闭类型检查,这段代码静态类型检查不会报错,但是运行时会crash,因为mic并没有foo()方法,
      // 所以建议大家在编程时不要直接使用dynamic
      mic = 1;
      print(mic.runtimeType); //int 说明类型是可变的
      print(mic); //1
      

3.显式声明可以推断出的类型

  • String name='Bob';
    

4 . 通过final const 声明不可变变量 下面有介绍

final ,const(常量)

使用过程中从来不会被修改的变量(可以称为常量),

  • 可以使用final或const

  • Fianl变量的值只能被设置一次;final定义的常量可以用变量来初始化

  • Const变量在编译阶段就已经固定(Const 时隐式的final类型最高级 final 变量)最高级 final 变量或类变量在第一次使用时被初始化。(编译时常量)

  • 实例变量可以是 final 类型但不能是 const 类型。 必须在构造函数体执行之前初始化 final 实例变量 —— 在变量声明中,参数构造函数中或构造函数的初始化列表中进行初始化

    • var a;
      //final定义的常量可以用变量来初始化
      final b=a;// 可以
      final time = new DateTime.now(); //Ok
      // const定义的是编译时常量,只能用编译时常量来初始化
      const c=a;// error
      const time = new DateTime.now(); //Error,new DateTime.now()不是const常量
      
      
  • Const 关键字不仅可以用于声明常量变量。 还可以用来创建常量值,以及声明创建常量值的构造函数。 任何变量都可以拥有常量值。

  • 来点简单的描述

    • final const 用来修饰不可变变量

      • 啥不可变变量 就是常量。。
    • 声明必须赋值

      • 区别

        • final 可以赋值为变量 在运行前确定其值即可

        • const 赋值必须为编译时常量,因为其编译时会检测

          • 顾名思义编译时常量只有编译前可以改变值 编译时无法改变

          • 比如将其作为参数传递 参考后面的 可选参数示例

          • 示例

            • //可传递List map 作为可选参数
              //const 表示编译时常量 故名思意 只有编译前可以改变值 编译后无法改变
              void doStuff(
                  {List<int> list = const [1, 2, 3],
                  Map<String, String> gifts = const {
                    'first': 'paper',
                    'secend': 'cotton',
                    'third': 'leather'
                  }}) {
                print('list: $list');
                print('gifts:$gifts');
              }
              //调用 注意看 const list 是不是发生了改变 默认值变了
              List<int> list = [4, 5, 6];
                Map<String, String> map = {
                  'one': 'param1',
                  'two': 'param2',
                  'three': 'param3'
                };
                doStuff(list: list, gifts: map);
              

默认值

未初始化的变量默认值是 null。即使变量是数字 类型默认值也是 null,因为在 Dart 中一切都是对象,数字类型 也不例外。

静态变量

通过static 修饰 类级别变量 全局类名调用访问

类型

Number

Dart 语言的 Number 有两种类型:

int

  • var x = 1;
    

double

  • var y = 1.1;
    var exponents = 1.42e5;
    //从 Dart 2.1 开始,必要的时候 int 字面量会自动转换成 double 类型。
    
    double z = 1; // 相当于 double z = 1.0.
    

类型转换

  • // String -> int
    var one = int.parse('1');
    assert(one == 1);
    
    // String -> double
    var onePointOne = double.parse('1.1');
    assert(onePointOne == 1.1);
    
    // int -> String
    String oneAsString = 1.toString();
    assert(oneAsString == '1');
    
    // double -> String
    String piAsString = 3.14159.toStringAsFixed(2);
    assert(piAsString == '3.14');
    

String

Dart 字符串是一组 UTF-16 单元序列。

  • 字符串通过单引号或者双引号创建。

    • String name="Bob";
      String name='Bob';
      
  • 单引号或者双引号里嵌套使用引号

    • String msg="hello 'Bob' ,How are you";
      String msg2 = 'Hello "Bob" ,How are you';
      print(msg);
      print(msg2);
      //Hello 'Bob' ,How are you
      //Hello 'Bob' ,How are you
      
  • 字符串可以通过 ${expression} 的方式内嵌表达式。 如果表达式是一个标识符,则 {} 可以省略。

    • String name = "Bob";
       String msg = "Hello '$name' ,How are you";
       String msg2 = 'Hello "${name.toUpperCase()}" ,How are you';
       print(msg);
       print(msg2);
      //Hello 'Bob' ,How are you
      //Hello "BOB" ,How are you
      
  • 使用连续三个单引号或者三个双引号实现多行字符串对象的创建:

    • var msg3='''
       hello Bob
       How are you
       ''';
       print(msg3);
      //hello Bob 保留定义字符串格式
       // How are you
      
  • 使用r 前缀创建原始字符串

    • 原始(raw)字符串,在原始(raw)字符串中,字符表示的就是其本身,转义字符会失去意义。\n不是换行,而是普通的\n字符。

    • var s = r"In a raw string, even \n isn't special.";
      print(s);
      //In a raw string, even \n isn't special.
      

Boolean

Dart 使用 bool 类型表示布尔值。只有bool 类型的值是true 才被认为是true。 Dart 只有字面量 true and false 是布尔类型, 这两个对象都是编译时常量。

Dart 的类型安全意味着不能使用 if (*nonbooleanValue*) 或者 assert (*nonbooleanValue*)。 而是应该像下面这样,明确的进行值检查:

  • // 检查是否为空字符串
      var fullName = '';
      assert(fullName.isEmpty);
      if (fullName.isEmpty) {
        print('fullName null');
      }
    
      // 检查0
      var hitPoints = 0;
      assert(hitPoints <= 0);
    
      // 检查是否为null
      var unicorn;
      assert(unicorn == null);
    
      // 检查是否为NaN
      var iMeantToDoThis = 0 / 0;
      assert(iMeantToDoThis.isNaN);
    

List

  • Array 就是 List 对象, 通常称之为 List

    • 注意事项

    • 可以直接打印list包括list的元素,list也是一个对象。但是java必须遍历才能打印list,直接打印是地址值

    • 和java一样list里面的元素必须保持类型一致,不一致就会报错。

    • 和java一样list的下标从0开始。

      • List list = [10, 7, 23];
          // 输出[10, 7, 23]
          print(list);
        // 类型推断为int类型的list 存放其他类型将出错
        //list.add("1")//error
        
    • 如果集合里面有多个相同的元素“X”, 只会删除集合中第一个该元素

    • 非元素累固定型List 可以存放多种类型格式数据

      • List listMore = new List();
         listMore.add('1'); //String
         listMore.add(1); //int
         listMore.add(1.111); //double
         listMore.add(true); //boolean
         print(listMore);
        
    • 使用List的构造函数,也可以添加int参数

      • List testList = new List(10); //长度为10的list集合 表示List固定长度,不能进行添加 删除操作 添加数据会提示Exception
        
  • 创建list

    • //创建一个int类型的list 固定数据类型只能存放固定类型数据
       List intList = new List<int>();
      //非元素累固定型List 可以存放多种类型格式数据
        List listMore = new List();
        listMore.add('1'); //String
        listMore.add(1); //int
      //长度为10的list集合
      List testList = new List(10); 
      
  • 常用函数

    • var fruits = new List();
      
        // 添加元素
        fruits.add('apples');
      
        // 添加多个元素
        fruits.addAll(['oranges', 'bananas']);
      
        List subFruits = ['apples', 'oranges', 'banans'];
        // 添加多个元素
        fruits.addAll(subFruits);
      
        // 输出: [apples, oranges, bananas, apples, oranges, banans]
        print(fruits);
      
        // 获取List的长度
        print(fruits.length);
      
        // 获取第一个元素
        print(fruits.first);
      
        // 获取元素最后一个元素
        print(fruits.last);
      
        // 利用索引获取元素
        print(fruits[0]);
      
        // 查找某个元素的索引号
        print(fruits.indexOf('apples'));
      
        // 删除指定位置的元素,返回删除的元素
        print(fruits.removeAt(0));
      
        // 删除指定元素,成功返回true,失败返回false
        // 如果集合里面有多个“apples”, 只会删除集合中第一个改元素
        fruits.remove('apples');
      
        // 删除最后一个元素,返回删除的元素
        fruits.removeLast();
      
        // 删除指定范围(索引)元素,含头不含尾
      //  fruits.removeRange(start,end);
      
        // 删除指定条件的元素(这里是元素长度大于6)
        fruits.removeWhere((item) => item.length > 6);
      
        // 删除所有的元素
        fruits.clear();
        // 可以使用 sort() 函数来排序, 但是由于我们使用定义的数组类型不一样,就不能使用
        var sortList = [1, 2, 4, 5, 3, 6];
        // 根据语法提示: List.sort([(int, int) → int compare]) → void
        sortList.sort((a, b) => a.compareTo(b));
        print(sortList); // 输出[1, 2, 3, 4, 5, 6]
        sortList.sort((a, b) => b.compareTo(a));
        print(sortList); //[6, 5, 4, 3, 2, 1]
      

Set

  • 元素唯一且无序的集合

  • 实例

    • var names =new Set<String>();
      names.addAll(['dart', 'c#', 'j#', 'e#']);
      
  • 创建

    • var names =new Set<String>();
      names.addAll(['dart', 'c#', 'j#', 'e#']);
      Set<String> name = {} as Set<String>; // 这样也是可以的。
      Set<String> n=new Set<String>();
      Set ns=new Set();
      //Set ns=new Set(2);//不支持指定长度
      //var nams = {}; // 这样会创建一个 Map ,而不是 Set 。
      
  • 常用函数

    • 使用 add()addAll() 为已有的 Set 添加元素:

      • var elements = <String>{};
        elements.add('fluorine');
        elements.addAll(halogens);
        
    • 使用 .length 来获取 Set 中元素的个数:

      • var elements = <String>{};
        elements.add('fluorine');
        elements.addAll(halogens);
        assert(elements.length == 5);
        
    • 在 Set 字面量前增加 const ,来创建一个编译时 Set 常量:

      • final constantSet = const {
          'fluorine',
          'chlorine',
          'bromine',
          'iodine',
          'astatine',
        };
        // constantSet.add('helium'); // Uncommenting this causes an error
        

Map

  • Map 是用来关联 keys 和 values 的对象。 keys 和 values 可以是任何类型的对象。在一个 Map 对象中一个 key 只能出现一次。 但是 value 可以出现多次。

  • 创建map

    • Map companys = {};
      Map company=new Map();
      Map ma=Map();// 为什么不用new 因为new 在dart2.0 可选
      // 指定键值对类型
      var aMap = new Map<int, String>();
      Map<int,String> aMap = new Map<int, String>();
      
  • 数据添加

    • //初始化里面写key和value,每组键值对中间用逗号隔开。
       Map companys = {'Alibaba': '阿里巴巴', 'Tencent': '腾讯', 'baidu': '百度'};
      // 通过key-value添加
      companys["accenture"]="埃森哲";
      // 通过整体合并另一个map 泛型要一致
      var fruit = new Map();
      fruit["first"] = "apple";
      fruit.addAll(companys);
      //addEntries() 合并两个map 如果key有重复,被合并的map的value覆盖前者
      // 形势一 通过Map
      Map<String,int> map26 = {"a":1,"b":2,"c":3};
      Map<String,int> map27 = {"a":1,"b":4,"d":3,"e":5};
      map26.addEntries(map27.entries);
      //print(map26);//{a: 1, b: 4, c: 3, d: 3, e: 5}
      // 形式二 通过list<MapEntrie>
       List<MapEntry<String, String>> list = new List();
       list.add(MapEntry("keyadd", "valueAdd"));
       fruit.addEntries(list.reversed); //通过Iterable增加数据
      
  • 取出数据 通过key

    • var gifts = {'first': 'partridge'};
      assert(gifts['first'] == 'partridge');
      //若map中不存在要查找的key map返回null
      var gifts = {'first': 'partridge'};
      assert(gifts['fifth'] == null);
      
  • 通过.length函数获取当前map 的键值对个数

    • var m={'key1':'key','key1':'key1};
      assert(m.length==2);
      
  • 创建map运行时常量 要通过const

    • final constmap=const{'key1':'value1',
                           'key2':'value2',
                           'key3':'value3',};
      constmap['key1']='hello';//该行代码会报错 因为const 标明的变量值不可修改
      

Rune

谨慎使用 list 方式操作 Rune 。 这种方法很容易引发崩溃, 具体原因取决于特定的语言,字符集和操作。

在 Dart 中, Rune 用来表示字符串中的 UTF-32 编码字符

Unicode 定义了一个全球的书写系统编码, 系统中使用的所有字母,数字和符号都对应唯一的数值编码。 由于 Dart 字符串是一系列 UTF-16 编码单元, 因此要在字符串中表示32位 Unicode 值需要特殊语法支持

表示 Unicode 编码的常用方法是, \uXXXX, 这里 XXXX 是一个4位的16进制数。 例如,心形符号 (♥) 是 \u2665。 对于特殊的非 4 个数值的情况, 把编码值放到大括号中即可。 例如,emoji 的笑脸 是 \u{1f600}

String 类有一些属性可以获得 rune 数据。 属性 codeUnitAtcodeUnit 返回16位编码数据。 属性 runes 获取字符串中的 Rune 。

var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());

//使用String. fromCharCodes显示字符图形
Runes input = new Runes(
   '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
print(new String.fromCharCodes(input));
// 输出
// 👏
// [55357, 56399]
// [128079]
// ♥  😅  😎  👻  🖖  👍

Symbol

一个 Symbol 对象表示 Dart 程序中声明的运算符或者标识符。 你也许永远都不需要使用 Symbol ,但要按名称引用标识符的 API 时, Symbol 就非常有用了。 因为代码压缩后会改变标识符的名称,但不会改变标识符的符号。 通过字面量 Symbol ,也就是标识符前面添加一个 # 号,来获取标识符的 Symbol 。

#radix
#bar
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章