Flutter 扩展函数

老孟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();

toIntString 类型的扩展函数,运行出现如下异常:

但是如下代码是正确的:

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.dartstring_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: 使用 hideshow 来限制

import 'string_extension.dart';
import 'string_extension1.dart' hide StringExtension1;

String a = '10';
a.toInt();



你可能还喜欢


关注「老孟Flutter」
让你每天进步一点点


浏览 73
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报