详解Flutter(Dart)中的级联运算符(..)使用方法
发表时间: 2024-01-17 18:55
如果我们想对同一个对象执行一系列操作,那么我们应该使用 Cascades (. .)操作符。
使用级联运算符可以极大的减少代码量,使代码更加简洁。
class User { late String name; late int age; late bool isMale; void say(){ print("Hello, World!"); }}void main() {//不使用级联运算符 User user = User(); user.name = "Lintex"; user.age = 18; user.isMale = true; user.say(); //使用级联运算符 User user = User() ..name = "Lintex" ..age = 18 ..isMale = true ..say(); print('${user.name} is cool!');}
通过级联操作符可以形成链式调用,上面的代码其实是这样的。第一个点可以理解成返回这个对象,第二个点再调用属性或方法。
User user = User()..name = "Lintex"..age = 18..isMale = true..say();
级联操作符属于比较特殊的操作符,在其它语言中不多见。
List list = [];list..add(1)..add(2)..add(3)..add(4)..add(5)..remove(2);// list = [1, 3, 4, 5]
⚠️注意:级联操作后,返回值会丢失
List list = [];list..add(1)..add(2)..add(3)..add(4)..add(5)..reversed;// 期望输出 [5, 4, 3, 2, 1]// 实际输出 [1, 2, 3, 4, 5]
三个点的操作符是在级联操作符的基础上扩展出来的,它的功能:用来给List赋值,相当把一个List完全复制给另外一个List。鉴于这个功能,它经常用在给List赋值的场景中。
list2=[...list];// list2 = [1, 3, 4, 5]
应用场景:
_listView = ListView( shrinkWrap: true, children: [ ...list.map((e) => ListTile(title: Text(e)),).toList(), ...list2.map((e) => ListTile(title: Text(e)),).toList(), ], );
void main() { // 针对自定义类的调用,中规中矩 // 需要注意的是`hello()`方法,它有返回值,但是级联调用后 // 返回值丢失了 // String hello(String name) { // var value = 'hello $name'; // print(value); // return value; // } var model = Model() ..hello('world') ..sayHi('bill') ..sayGoodbye('bill'); /* output: hello world hi bill goodbye bill */ // 针对列表的级联 List<int> listInt = List() ..add(0) ..add(1) ..add(2) ..removeAt(1); print(listInt); // output: [0, 2] // 针对字典的级联 Map<String,dynamic> aMap = Map() ..putIfAbsent('name', ()=>'bill') ..putIfAbsent('name', ()=>'gate') ..addAll({'sex':'male', 'age':1}) ..remove('age'); print(aMap); // output: {name: bill, sex: male} // 一个Bug示范:对字符串的级联add,add结果均抛弃了 // 最后输出的是原字符串 String aStr = '' ..add('line1\n') ..add('line2\n') ..add('line3'); print('aStr:${aStr}_${aStr.length}'); // output: aStr:_0 // 可变字符串的正确打开方式 StringBuffer aStr2 = StringBuffer() ..write('hello ') ..write('world'); print('aStr2:${aStr2}_${aStr2.length}'); // aStr2:hello world_11 // 对异步方法处理 // 由于异步方法的触发并需要特殊条件,所以级联调用跟普通方法一样 // 区别是异步方法仍然会异步执行,某段时间后才会执行。 class Model { .. Future<void> asyncSayHi(String name) { return Future.delayed(Duration(seconds: 1), (){ print('say hi from future $name'); }); } } var model1 = Model() ..hello('world') ..sayHi('bill') ..sayGoodbye('bill') ..asyncSayHi('bill'); // output: // hello world // hi bill // goodbye bill // ..(其他输出) // say hi from future bill // 目前的使用场景-解析json到对象 static Attachment json2Attachment(dynamic json) { if (json == null || json is Map == false) { return null; } var result = Attachment() ..id = '${json["id"]}' ..filename = json["filename"] ..contentId = json["contentId"] ..contentType = json["contentType"] ..encoding = json["encoding"] ..estimateSize = json["estimateSize"] ..contentLength = json["contentLength"] ..inlined = json["inlined"] ..type = json["type"]; return result; }