簡(jiǎn)介:
從2.7及以上的dart版本開始,讓人殷切期待的擴(kuò)展函數(shù)來了惊完。當(dāng)你想擴(kuò)展別人的函數(shù)庫(kù)或者官方的SDK稽莉,如果通過更改api的方式則意味著你需要重建一個(gè)代碼分支,維護(hù)一個(gè)分支是相當(dāng)麻煩的事情坛猪, 如果這個(gè)時(shí)候使用擴(kuò)展方法將是非常方便的脖阵。擴(kuò)展不僅可以定義方法,還可以定義getter墅茉,setter和operator命黔。雖然擴(kuò)展方法中不能用于用dynamic類型,但卻支持更強(qiáng)大的泛型擴(kuò)展就斤『纺迹總有人吐槽flutter開發(fā)widget嵌套太深的問題,擴(kuò)展函數(shù)的使用能夠讓代碼的結(jié)構(gòu)變得極為簡(jiǎn)潔洋机,加上泛型擴(kuò)展的使用可以使代碼鏈?zhǔn)秸{(diào)用一鏈到底坠宴。
原理:
擴(kuò)展函數(shù)調(diào)用起來跟原生方法一樣自然,使用起來也非常方便绷旗,但是這樣的用法會(huì)不會(huì)帶來性能方面的問題呢喜鼓?其實(shí)擴(kuò)展函數(shù)的本質(zhì)是針對(duì)接收者的靜態(tài)類型進(jìn)行了解析,即擴(kuò)展方法是靜態(tài)解析的衔肢,擴(kuò)展函數(shù)的實(shí)現(xiàn)非常簡(jiǎn)單庄岖,它沒有修改接受者類型的成員,僅僅是通過靜態(tài)方法來實(shí)現(xiàn)的角骤,它們與調(diào)用靜態(tài)函數(shù)一樣快速隅忿。
廢話少說,下面以本人開發(fā)中的使用的經(jīng)驗(yàn)舉幾個(gè)例子加以說明邦尊。
widget擴(kuò)展:
extension WidgetExt on Widget {
Widget padding(EdgeInsetsGeometry padding) {
return Padding(
child: this,
padding: padding,
);
}
Material gesture({
GestureTapCallback onTap,
GestureTapCallback onDoubleTap,
GestureLongPressCallback onLongPress,
}) {
return Material(
child: InkWell(
child: this,
onTap: onTap,
onDoubleTap: onDoubleTap,
onLongPress: onLongPress,
),
);
}
}
String擴(kuò)展:
extension StringExt on String {
double toDouble() {
return double.parse(this);
}
int toInt() {
return int.parse(this);
}
bool isMobile(){
return RegExp(r'^((13[0-9])|(14[5,7,9])|(15[^4])|(18[0-9])|(17[0,1,3,5,6,7,8])|(19)[0-9])\d{8}$').hasMatch(this);
}
}
Object擴(kuò)展:
extension ObjectExt on Object {
bool isNullOrEmpty() {
if (this is String)
return (this as String).isEmpty;
else if (this is Iterable) return (this as Iterable).isEmpty;
return this == null;
}
}
bool擴(kuò)展:
extension BoolExt on bool {
bool not() {
return !this;
}
bool and(bool val) {
return this && val;
}
bool or(bool val) {
return this || val;
}
}
泛型擴(kuò)展:
extension AllExt<T> on T {
T apply(f(T e)) {
f(this);
return this;
}
R let<R>(R f(T e)) {
return f(this);
}
}
調(diào)用示例如下:僅簡(jiǎn)單舉幾個(gè)調(diào)用例子背桐,其余的調(diào)用有興趣者自行嘗試。
實(shí)現(xiàn)單層沒有嵌的padding和點(diǎn)擊事件
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
)
.padding(EdgeInsets.all(10))
.gesture(onTap: () {
}),
],
),
),
實(shí)現(xiàn)String正則的判斷
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'13646176072'.isMobile()?"手機(jī)號(hào)":"不是手機(jī)號(hào)",
),
],
),
),
bool類型的鏈?zhǔn)秸{(diào)用
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
['13646176072', "fgdgdfgdf", 'trtreter']
.isNullOrEmpty()
.not()
.and(true)
.or(false)
.toString(),
),
],
),
),
泛型擴(kuò)展的鏈?zhǔn)秸{(diào)用:這個(gè)用法非常值得一提蝉揍,在原生開發(fā)中kotlin的語(yǔ)法糖是相當(dāng)牛掰的链峭,kotlin能夠使代碼的編寫鏈成一整個(gè)鏈而不使用一個(gè)中間變量,這樣使得代碼優(yōu)雅疑苫,封裝的更完美熏版。幸運(yùn)的是dart雖然沒有提供很多的語(yǔ)法糖,但卻提供了泛型擴(kuò)展函數(shù)捍掺,我們可以依此自定義非常強(qiáng)大的語(yǔ)法糖撼短,調(diào)用示例如下,經(jīng)過層層無聊的轉(zhuǎn)化得到一個(gè)字符串而沒有定義一個(gè)函數(shù)挺勿,也沒有中間變量造成變量污染:
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
People(11, 1, 30)
.apply((val) {
val.introduce = "我今年${val.age}${val.sex}${val.weight}";
}).let((val) {
if (val.sex == 1) return Monkey(11, 0, 30);
return Monkey(11, 1, 30);
}).let((val) {
if (val.sex == 1) return "大猴子";
return "程序猿";
}).let((val) {
return "整這么多干啥呢曲横,好麻煩啊";
})),
],
),
),
通過以上示例可以看出擴(kuò)展函數(shù)是很有可玩性的,她能大大提高代碼質(zhì)量,讓編程變得有趣禾嫉,何不一起來探討探討呢灾杰?