Flutter 扩展函数
共 3982字,需浏览 8分钟
·
2021-04-20 13:13
Extension methods 就是我们常说的扩展函数,像 Kotlin 等语言也有 扩展函数 的特性,因此如果你了解其他语言的扩展函数,Dart 中的扩展函数与其他语言基本一致。
扩展函数最低版本要求:
environment:
sdk: ">=2.7.0 <3.0.0"
注意:空安全的最低版本是 2.12.0。
基础
那么什么是扩展函数?
简单理解,扩展函数就是在现有的库或者类中扩展一个函数,比如,我们希望将一个整数字符串转换为 int 类型整数,正常情况下,实现如下:
int.parse('10');
但是此中写法不是很美观,比较美观的写法是这样的:
'10'.toInt();
但是 String 类型并没有 toInt 方法,这时扩展函数就有了用武之地,我们给 String 扩展一个 toInt 方法:
extension StringExtension on String {
int toInt() {
return int.parse(this);
}
}
扩展函数使用关键字 extension。 StringExtension:是扩展函数的名称。 on :关键字后接需要扩展的类型。 大括号 :内部是扩展的方法。
有人觉得这个例子并不能体现 扩展函数 的强大之处,看下面这个例子,假设有一个第三方库的类 Person:
class Person {
final String name;
Person(this.name);
}
有2个实例 person1 和 person2,我们希望这个2个实例相加,返回一个 Person 对象且name 值为2个name的拼接,中间用 , 隔开,不使用扩展函数实现:
Person add(Person person1,Person person2){
return Person('${person1.name},${person2.name}');
}
下面使用扩展函数实现:
extension PersonExtension on Person {
Person operator +(Person person) {
return Person('${this.name},${person.name}');
}
}
使用:
Person person1 = Person('lao');
Person person2 = Person('meng');
Person p = add(person1, person2);
print('${p.name}');
Person p1 = person1 + person2;
print('${p1.name}');
输出结果:
flutter: lao,meng
flutter: lao,meng
结果都是一样的,都可以实现要求,但扩展函数的可读性更好。
注意:扩展函数可以实现的功能,使用工具类(方法)同样也可以实现。
var 和 dynamic
不能对 dynamic 类型使用扩展函数,下面的用户在运行时出现异常:
dynamic a = '10';
a.toInt();
toInt 是 String 类型的扩展函数,运行出现如下异常:
但是如下代码是正确的:
var b = '10';
b.toInt();
因为 b 以及被推断为 String 类型,所以可以使用扩展函数。
通过上面的例子,我们已经对扩展函数有了一定的了解,扩展函数除了可以扩展方法外,还可以扩展属性、操作符。
class Person {
String name;
Person(this.name);
}
扩展函数:
extension PersonExtension on Person {
// 扩展操作符 +
Person operator +(Person person) {
return Person('${this.name},${person.name}');
}
// 扩展 getter 属性
int get nameLength => this.name.length;
//已经存在的方法不能扩展
// String toString(){
// return 'name:${this.name},age:${this.age}';
// }
//扩展 方法
String log() {
return 'name:${this.name}';
}
}
使用:
Person person = Person('flutter');
print('${person.nameLength}');
print('${person.log()}');
解决冲突
假设现在有2个扩展函数,分别在 string_extension.dart 和 string_extension_1.dart 文件中,string_extension.dart 代码如下:
extension StringExtension on String {
int toInt() {
return int.parse(this);
}
}
string_extension_1.dart 代码如下:
extension StringExtension1 on String {
int toInt() {
return int.parse(this);
}
double toDouble() {
return double.parse(this);
}
}
string_extension_1.dart 中的代码比 string_extension.dart 多了一个 toDouble 方法。
引入2个扩展函数并使用 toInt 方法:
import 'string_extension.dart';
import 'string_extension1.dart';
String a = '10';
a.toInt();
此时,无法编译通过,异常如下:
异常原因:2个扩展函数中都有 toInt 方法。
解决方案1: 指定使用哪一个扩展函数
String a = '10';
StringExtension(a).toInt();
解决方案2: 使用 hide 和 show 来限制
import 'string_extension.dart';
import 'string_extension1.dart' hide StringExtension1;
String a = '10';
a.toInt();