Dart速通笔记

笔记 · 2023-11-01 · 581 人浏览

基础表达式

变量

  • 如果变量可以为空,需要用?

    String? name //可以为null
    String name //不允许为null
  • late前缀允许懒加载,使用该前缀的变量在被使用时才被初始化,即使已经被设了初值

    late String temperature = readThemometer();//使用时才会被初始化
  • final为前缀的变量不能被重新赋值为另一个对象,但该变量的字段可以

    final obj = SomeClass();
    obj.field1 = 'new value';  // 这是允许的
    obj = AnotherClass();  // 这是不允许的
  • const为前缀的变量自己和自己的字段都不被允许修改

    const obj = SomeConstClass();
    obj.field1 = 'new value';  // 这是不允许的
    obj = AnotherClass();  // 这也是不允许的
  • 你可以改变一个没有finalconst前缀的变量,即使这个变量以前是const

    var foo = const[];
    foo = [1, 2, 3];
  • 所以变量都是对象

操作符

  • (..,?..)级联

    • 你可以使用..来对同一对象进行一系列操作

      var paint = Paint()
        ..color = Colors.black
        ..strokeCap = StrokeCap.round
        ..strokeWidth = 5.0;

      等同于

      var paint = Paint();
      paint.color = Colors.black;
      paint.strokeCap = StrokeCap.round;
      paint.strokeWidth = 5.0;
    • 对于可以为空时使用?..来确保当对象是null时,级联中的操作不会被执行

      var myObject;
      myObject?..method1()..method2();//如果myObject为null,后续method1(),method2()不执行
    • 可以嵌套使用

      final addressBook = (AddressBookBuilder()
            ..name = 'jenny'
            ..email = 'jenny@example.com'
            ..phone = (PhoneNumberBuilder()
                  ..number = '415-555-0100'
                  ..label = 'home')
                .build())
          .build();
    • 如果你试图在一个返回 voidnull 的函数上使用级联操作,那么代码将会出错或者不会按预期工作。

      var sb = StringBuffer();
      sb.write('foo')
        ..write('bar'); // Error: method 'write' isn't defined for 'void'.

类型

记录

  • 记录表达式是以逗号分隔的命名或位置字段列表,用括号括起来:

    var record = ('first', a: 2, b: true, 'last');
  • 记录类型注释是以逗号分隔的类型列表,用括号括起来。您可以使用记录类型注解来定义返回类型和参数类型。

    (int, int) swap((int, int) record) {
      var (a, b) = record;
      return (b, a);
    }
  • 在记录类型注释中,命名字段位于类型和名称成对的大括号分隔部分内,在所有位置字段之后。在记录表达式中,名称在每个字段值之前,冒号在后:

    //int是位置字段,a是命名字段
    ({int a, bool b}) record;
    
    record = (a: 123, b: true);
  • 两个记录的命名字段名不同,其类型也就不同

    ({int a, int b}) recordAB = (a: 1, b: 2);
    ({int x, int y}) recordXY = (x: 3, y: 4);
    
    // Compile error! These records don't have the same type.
    // recordAB = recordXY;
  • 可以为位置字段命名,但这些名称纯粹是为了记录,并不影响记录的类型

    (int a, int b) recordAB = (1, 2);
    (int x, int y) recordXY = (3, 4);
    //a,b,x,y是位置字段的名字而非命名字段
    
    recordAB = recordXY; // OK.
  • 已命名字段使用同名的获取器。位置字段使用名称为 $<position> 的获取器,而不使用已命名字段:

    var record = ('first', a: 2, b: true, 'last');
    
    print(record.$1); // Prints 'first'
    print(record.a); // Prints 2
    print(record.b); // Prints true
    print(record.$2); // Prints 'last'
  • 如果两条记录具有相同的形状(字段集),且相应字段的值相同,则这两条记录是相等的。由于已命名字段的顺序不是记录形状的一部分,因此已命名字段的顺序不会影响相等性。
  • 该类型可以用于返回多个值

    // (String, int)表示使用该类型的记录作为返回值
    (String, int) userInfo(Map<String, dynamic> json) {
      return (json['name'] as String, json['age'] as int);
    }
    
    final json = <String, dynamic>{
      'name': 'Dash',
      'age': 10,
      'color': 'blue',
    };
    
    var (name, age) = userInfo(json);
    
    /* Equivalent to:
      var info = userInfo(json);
      var name = info.$1;
      var age  = info.$2;
    */
Theme Jasmine by Kent Liao