flutter【8】dart語言--泛型
泛型
例如基礎陣列型別,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).