dart系列之:你的地盤你做主,使用Extension對類進行擴充套件

flydean發表於2021-12-31

簡介

一般情況要擴充套件一個類,需要繼承這個類,這是在大多數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<T> 進行擴充套件,新增了getter,操作符和split方法。

總結

以上就是2.7的新特性,類的擴充套件。

本文已收錄於 http://www.flydean.com/26-dart-extension-method/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!

相關文章