泛型
例如基礎數組類型,List<E>, 其中的E就是泛型,參數化類型,也可以用其他單個大寫字母表示,如 E,T,S,K,V等。
使用泛型可以方便檢查工具對代碼進行審查
var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
names.add(42); // Error
使用泛型可以減少重複代碼
//不用泛型,存儲 Object
abstract class ObjectCache {
Object getByKey(String key);
void setByKey(String key, Object value);
}
//不用泛型,存儲 String
abstract class StringCache {
String getByKey(String key);
void setByKey(String key, String value);
}
//使用泛型,則可以省去爲每一種類型單獨編寫代碼
abstract class Cache<T> {
T getByKey(String key);
void setByKey(String key, T value);
}
List 和 Map 字面量也可以參數化
List參數化在中括號之前添加 <type>
,Map 參數化在大括號之前添加 <keyType, valueType>
。
var names = <String>['Seth', 'Kathy', 'Lars'];
var pages = <String, String>{
'index.html': 'Homepage',
'robots.txt': 'Hints for web robots',
'humans.txt': 'We are people, not machines'
};
構造方法使用參數化類型
在調用構造方法時,在類名後面使用尖括號,尖括號內填入一個或多個類型來指定泛型。
var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
var nameSet = Set<String>.from(names);
var views = Map<int, View>();
Generic collections and the types they contain
dart 中的泛型是固化的,就是在運行時可以判斷其具體類型。
var names = new List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
print(names is List<String>); // true
注意 is 表達式只是判斷集合的類型,而不是集合裏面具體對象的類型。在生產模式,List<String> 變量可以包含非字符串類型對象。對於這種情況,可以選擇分別判斷每個對象的類型或者處理類型轉換異常 (參考 Exceptions)。
注意:Java 中的泛型信息是編譯時的,泛型信息在運行時是不純在的。在 Java 中你可以測試一個對象是否爲 List,但是無法測試一個對象是否爲List<String>。
限制泛型類型
使用關鍵字 extends 限制參數的類型
class Foo<T extends SomeBaseClass> {
// Implementation goes here...
String toString() => "Instance of 'Foo<$T>'";
}
class Extender extends SomeBaseClass {...}
//使用時可以傳入 SomeBaseClass 或者其子類
var someBaseClassFoo = Foo<SomeBaseClass>();
var extenderFoo = Foo<Extender>();
//也可以不傳入參數,默認爲 SomeBaseClass
var foo = Foo();
print(foo); // Instance of 'Foo<SomeBaseClass>'
//傳入其他類型的參數則會報錯
var foo = Foo<Object>();//error
泛型方法
需要dart1.2.1以上版本纔可以使用泛型方法
T first<T>(List<T> ts) {
// Do some initial work or error checking, then...
T tmp = ts[0];
// Do some additional checking or processing...
return tmp;
}
這裏的 first (<T>) 泛型可以在如下地方使用參數 T :
- 函數的返回值類型 (T).
- 參數的類型 (List<T>).
- 局部變量的類型 (T tmp).