

Dart 点将台 | extension 拓展方法
source link: https://mp.weixin.qq.com/s?__biz=MzI0NjU3MDA4NQ%3D%3D&%3Bmid=2247484848&%3Bidx=1&%3Bsn=73bde3924c252c6ff9ad99018291bb37
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

1. Dart 的拓展方法介绍
如果我们需要判断该字符串 是否是手机号
,需要写个 正则
来校验,如果用的地方很多,每个地方都要些校验逻辑,或者抽离一个工具类辅助校验。但也没有想过可以直接使用 字符串.isPhone()
来校验?在 Dart 2.7,添加了 拓展方法
的特性,这使我们在 不修改
已有源码的基础上,可以方便地拓展 已有类型
的方法。代码如下:
main(){
String number = "18715079389";
print(number.isPhone()); // true
String number2 = "28715079389";
print(number2.isPhone()); // false
}
extension JudgeString on String {
bool isPhone(){
return RegExp(r'^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$').hasMatch(this);
}
}
拓展方法的语法如下,关键字为 extension
、 on
,其中 名称
任意,类型就是待拓展类。 {}
内可以包含若干个方法体。

2. 拓展方法中的 this
拓展方法中可以使用 this
对象,那么这个 this
对象是什么呢?第一感觉,应该指的是调用这个方法的对象。下面通过一个小案例测试一下是不是这样的。如下,对 List
类进行拓展,有一个 check
方法,需要一个 List
入参,这样我们可以比较 入参
和 this
的内存地址是不是同一个,使用 identical
方法进行比较。结果是 true 。这就说明:
拓展方法中的 this
确实指代的是 方法的调用者
。
main() {
List<int> list = [0, 1, 2, 3];
list.check(list);
}
extension ListPrint on List {
void check(List list) {
print(identical(list, this)); // true
}
}
另外也可以进行 运算符重载
的拓展。比如 DateTime
类中只是使用 add 方法进行加法计算。可以通过 extension
对原有的 DateTime
类进行运算符拓展。代码如下:
main() {
final DateTime birthday = DateTime(1994, 3, 28, 14, 28);
// 1994-07-06 16:30:00.000
print(birthday + Duration(days: 100, hours: 2, minutes: 2));
}
extension DateTimeExt on DateTime {
DateTime operator +(Duration other) => this.add(other);
}
3.拓展方法的注意点
拓展方法只能由对象调用,其名称 不可以
实例化使用。

拓展方法中 不可以
声明普通成员变量。

那你也许会有疑问,拓展名不能用,那他存在的价值是什么?拓展方法中虽然不能定义普通成员变量,但是可以定义 静态成员
。通过 名称.静态成员
可以访问。

那能拓展 静态方法
吗? 其实我们可以反过来想一想,拓展方法需要对象调用。静态方法是在实例化之前就已确定的,所以 this 是不可能在 static 方法中使用的。

这时可能有小机灵鬼会说,不用 this 不就行了吗?那不用 this ,拓展方法的意义何在?如下,在 ListPrint
中定义的静态方法,只能通过 ListPrint
调用,不能通过 List
调用。所以静态相关的和待拓展类并没有关系,是属于自己的行为。

4.拓展方法的优缺点
拓展方法的好处在使用起来非常方便,语义性也很强,复用性也很好,还能装逼于无形。
但 是药三分毒
,如果名字没起好,或说拓展的方法非常杂乱,那在别人眼中,阅读你的代码将会非常吃力。或者会让别人疑惑: 为什么我的类里没有这个方法,难道我的版本太低了?
这样,对于拓展方法而言,就会出现一些混乱,这也是 使用者
和 观看者
的信息不对等,而出现的理解性偏差。
其实这和贫富差距一样,是很难避免的,也并没有什么好的解决方案。在写拓展方法时注意命名的合理,多写注释,多写注释,多写注释,这样可以让 信息尽可能多的对等
,毕竟你的脑子里想什么,别人很难捉摸出来。
其次就是规范性,如果拓展方法可以有一个 标识来区分
,这样就能让信息拥有 辨识性
。比如,拓展方法的末尾都加 $
字符。如果这成为了一种拓展规范,这样当读码的人看到,就可以迅速意识到这个方法是 拓展的
,从而减少不必要的疑虑。

另外, 写码者
,可以通过 $
来触发提示,获取自己拓展的方法,能更快找到。

这里只是我的一个小想法,至于为什么是 $
, $
为什么在末尾,其实并不重要,重要的是规范性的普及。就像章北海的最后一句话: 没关系的,都一样
。关于 Dart 的拓展方法也说得差不多了,本文就到这里,谢谢观看 ~
Recommend
-
41
温故而知新,可以为师矣 至美不过回首,往事重重,顾来时,荆棘漫漫,血浸途中。 今铜衣铁靴,再行来路,任荆棘漫漫,唯落绿叶残枝。 ----张风捷特烈 复制代码 零、前言 1.本文的知识点 1).Act
-
15
Linux - @yanqiyu - https://lists.centos.org/pipermail/centos-announce/2020-December/048208.htmlhttps://www.redhat.com
-
9
1.对 const 的认知 80% 的人对 const 的认知,只停留在 const 修饰的量不可以被修改,这一条。甚至有些人对什么时候可以用 const 修饰还比较模糊。首先看一下内置的类型变量对象的构造,如 int 、 doub...
-
9
一、函数的定义 1. Dart 中的函数定义 在 Dart 中,没有函数关键字,定义格式如下: 1
-
15
一、 DateTime 的成员属性 DateTime 是和日期、时间相关的类,自身比较简单,本文从源码的角度看看内部实现,能不能寻找到一些有价值的知识,如果没有的话,就当是巩固基础啦。 当前sdk : Flutter 1.22.6 --
-
14
1. operator 关键字的使用 Dart 中支持对运算符的重载,这里先通过一个小例子看看如何使用 operator 关键字。我们说 捷特比龙少大 , 一般指的是年龄。如下的 Person 对象中重写 >
-
5
一、Flutter 初始项目中的包 1. 如何查看项目的存在的包 在 AndroidStudio 中,可以在 External Libraries 下查看存在的 Dart Packages 。如下是一个新建项目存在的内置包。这些包中定...
-
4
京津冀节点将领跑“东数西算”工程建设_IDC国内资讯_中国IDC圈 京津冀节点将领跑“东数西算”工程建设 中国通信工业协会数据中心委员会发布的 《京津冀数据中心新基建发展》显示:“京津冀地区是中国IDC(互...
-
6
新浪VR > 正文页 Optimism推出Optimism生态基金会 重点将转向基于身份的NFT治理层...
-
3
特定养老储蓄试点将开启,银行掘金个人养老金账户面临考题 作者:FYQ 发布时间: 2022-09-22 11:55
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK