基础表达式
变量
如果变量可以为空,需要用
?
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(); // 这也是不允许的
你可以改变一个没有
final
、const
前缀的变量,即使这个变量以前是constvar 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();
如果你试图在一个返回
void
或null
的函数上使用级联操作,那么代码将会出错或者不会按预期工作。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; */