如何使用
dart extension 的使用场景是无法修改原类的时候,通过扩展的方式来增加原类的方法,也可以增加 getter,setters,and operators。
比如
| 1 | int.parse('42') | 
如果 String 有 pareseInt 方法,我们可以这样写
| 1 | '42'.parseInt() | 
为了达到这个目标,需要写一个 Extension
| 1 2 3 4 5 6 | extension NumberParsing on String {   int parseInt() {     return int.parse(this);   }   // ··· } | 
然后就可以使用了。
| 1 2 3 4 5 | // Import a library that contains an extension on String. import 'string_apis.dart'; // ··· print('42'.padLeft(5)); // Use a String method. print('42'.parseInt()); // Use an extension method. | 
处理冲突
注意到前面加的 NumberParsing 了吗?这个是为 extension 起的名字。起名字的作用是有冲突的时候可以方便的控制显隐。比如 NumberParsing2 也定义了 parseInt 方法与 NumberParsing 的 parseInt 冲突,如果只想要 NumberParsing 的 parseInt,只需要把 NumberParsing2 隐藏就好了。
| 1 2 3 4 5 6 7 8 9 10 | // Defines the String extension method parseInt(). import 'string_apis.dart'; // Also defines parseInt(), but hiding NumberParsing2 // hides that extension method. import 'string_apis_2.dart' hide NumberParsing2; // ··· // Uses the parseInt() defined in 'string_apis.dart'. print('42'.parseInt()); | 
或者可以 给 NumberParsing2 经起个别名
| 1 2 3 4 5 6 7 8 9 10 | import 'string_apis.dart'; import 'string_apis_2.dart' as rad; print(NumberParsing('42').parseInt()); // Use the ParseNumbers extension from string_apis_3.dart. print(rad.NumberParsing('42').parseInt()); // Only string_apis_3.dart has parseNum(). print('42'.parseNum()); | 
泛型 extension
可以只给 int 类型的 list 加 sum 方法,其它类型的 list 不能使用 sum。
| 1 2 3 4 5 | // Import a library that contains an extension on String. import 'string_apis.dart'; // ··· print('42'.padLeft(5)); // Use a String method. print('42'.parseInt()); // Use an extension method. | 
| 1 2 3 | ["1", "2", "3"].sum();  //Error: The method 'sum' isn't defined for the class 'List<String>' [1,2,3].sum(); // ok, output 6 | 
要注意的问题
dart extension 不可以用于 dynamic 类型
| 1 2 | dynamic d = '2'; print(d.parseInt()); // Runtime exception: NoSuchMethodError | 
dart extension 权限很大,这也意味着,很可能被过度使用。所以在使用的时候一定要再三权衡,一定要可读性,可维护性优先。
上面的代码是比较简单的,但是如果类型比较复杂,不明确指定类型,类似如下的形式,也是可能会报错的:
| 1 2 3 4 5 6 7 8 9 10 | class Provider {  late final d;  Provider() {     this.d = '';     this.d.parseInt(); // Runtime exception: NoSuchMethodError   } } |