如何使用
dart extension 的使用场景是无法修改原类的时候,通过扩展的方式来增加原类的方法和属性。
比如
int.parse('42') 复制代码
如果 String 有 pareseInt 方法,我们可以这样写
'42'.parseInt() 复制代码
为了达到这个目标,需要写一个 Extension
extension NumberParsing on String { int parseInt() { return int.parse(this); } // ··· } 复制代码
然后就可以使用了。
// 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 隐藏就好了。
// 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 经起个别名
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。
extension on List<int> { int sum() { return fold(0, (sum, v) => sum + v); } } 复制代码
["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 类型
dynamic d = '2'; print(d.parseInt()); // Runtime exception: NoSuchMethodError 复制代码
dart extension 权限很大,这也意味着,很可能被过度使用。所以在使用的时候一定要再三权衡,一定要可读性,可维护性优先。