dart系列之:你的地盤你做主,使用Extension對類進行擴展
簡介
一般情況要擴展一個類,需要繼承這個類,這是在大多數java或者其他面向對象語言中要做的事情。
但是有些時候擴展類並不是特別好用,首先在有些語言中,有些類是禁止被擴展的。即使可以被擴展,但是擴展之後的類是一個新的類,而不是原來的父類,所以在使用的過程中可能會出現一些類型轉換的問題。
那麼在dart中是怎麼解決這個問題的呢?
dart中extension的使用
dart在2.7之後,引入了extension,用來對類的方法進行擴展。
到底怎麼擴展呢?我們舉個例子.
我們可以將字符串轉換為int,通過調用int的parse方法,如下所示:
int.parse('18')
但是通過int類來進行轉換通常不太直觀,我們希望能夠在String類中提供一個toInt的方法,可以直接調用,將字符串轉換成為int。
'18'.toInt()
但是很遺憾,String並沒有提供toInt的方法,所以我們可以通過extension來對String進行擴展:
extension StringToNumber on String {
int toInt() {
return int.parse(this);
}
// ···
}
如果這個文件的名字叫做string_to_number.dart,那麼我們可以這樣使用:
import 'string_to_number.dart';
// ···
print('18'.parseInt());
dart中方法擴展最為方便的是,你只要引入對應的lib,使用的時候甚至都不知道在使用lib的擴展。
當然,並不是所有的類都可以使用extention進行擴展。比如dynamic類型就不能進行擴展。
但是使用var類型,只要該類型可以被推斷出來,那麼就可以使用extention擴展。
API衝突
既然可以對lib進行擴展,那麼就有可能出現API衝突的情況。那麼怎麼解決API衝突呢?
比如我們需要使用兩個lib擴展文件,extention1.dart和extention2.dart.但是兩個擴展文件中都定義了parseInt方法對String進行擴展。
如果同時引用的話,就會出現問題。
這時候可以使用show或者hide來限制具體使用哪一個擴展文件的中的方法。
import 'extention1.dart';
import 'extention2.dart' hide StringToNumber2;
print('18'.parseInt());
還有一種情況就是顯示調用extension,如下所示:
import 'extention1.dart';
import 'extention2.dart';
print(StringToNumber('18').parseInt());
print(StringToNumber2('18').parseInt());
通過extention的名字來進行區分。
如果兩個extention的名字也相同的話,那麼可以通過prefix來進行區分:
import 'extention1.dart';
import 'extention2.dart' as ext2;
print(StringToNumber('18').parseInt());
print(ext2.StringToNumber('18').parseInt());
extention的實現
實現擴展很簡單,實現語法如下:
extension <extension name> on <type> {
(<member definition>)*
}
下面是一個擴展String的例子:
extension NumberParsing on String {
int parseInt() {
return int.parse(this);
}
double parseDouble() {
return double.parse(this);
}
}
extension還可以擴展泛型參數:
extension MyFancyList<T> on List<T> {
int get doubleLength => length * 2;
List<T> operator -() => reversed.toList();
List<List<T>> split(int at) => [sublist(0, at), sublist(at)];
}
上面的實現是對List
總結
以上就是2.7的新特性,類的擴展。
本文已收錄於 //www.flydean.com/26-dart-extension-method/
最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!