這篇翻譯的不好 如果你看API文檔中的數組篇,你會發現類型一般寫成List.的寫法表示通用類型的數組(未明確指定數組中的數據類型)。通常情況泛型類型用E,T,S,K,V表示。 Why use generics? 為什麼用泛型 泛型是類型安全的(意思是你必須指定數據的類型),但是它的寫法比硬編碼指定類 ...
- 這篇翻譯的不好
如果你看API文檔中的數組篇,你會發現類型一般寫成List
Why use generics? 為什麼用泛型
泛型是類型安全的(意思是你必須指定數據的類型),但是它的寫法比硬編碼指定類型高效的多:
- Properly specifying generic types results in better generated code.
- 減少重覆代碼
如果你想讓數組只有String值,定義為List
var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
names.add(42); // Error
另一個使用泛型是原因是為了減少重覆代碼。泛型讓你通過一個單一類可以適配多種類型的數據操作,同時可以進行靜態代碼檢查(比如,類型安全檢查)。
abstract class ObjectCache {
Object getByKey(String key);
void setByKey(String key, Object value);
}
上面代碼是對Object類型操作,在沒用泛型的情況下,你想對String類型操作,就得重新定義一個類
abstract class StringCache {
String getByKey(String key);
void setByKey(String key, String value);
}
後面,你如果相對num類型操作,還得重新定義一個類。
而泛型就可以解決上面的問題,它通過對類型參數化,實現一個類針對多種數據類型操作的適配。
abstract class Cache<T> {
T getByKey(String key);
void setByKey(String key, T value);
}
Using collection literals 使用集合
List和map的字面量
List和map的字面量方式可以用指定類型參數。
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'
};
Using parameterized types with constructors 構造器中使用類型參數
var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
var nameSet = Set<String>.from(names);
下麵是map的泛型構造寫法:
var views = Map<int, View>();
Generic collections and the types they contain
Dart的泛型類型是在運行時綁定的,這樣,在運行時,可以知道List內具體類型。
var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
print(names is List<String>); // true
註意:java中,泛型是採用擦除的方式,它在運行時,其實對象都是Object類型或者泛型的約束父類。
Restricting the parameterized type
當泛型時,希望限制參數的類型範圍,可以用extends關鍵字約束。
class Foo<T extends SomeBaseClass> {
// Implementation goes here...
String toString() => "Instance of 'Foo<$T>'";
}
class Extender extends SomeBaseClass {...}
添加約束後,只要是指定的父類或者其子類都可以作為泛型參數。
var someBaseClassFoo = Foo<SomeBaseClass>();
var extenderFoo = Foo<Extender>();
也可以不指定泛型參數。
var foo = Foo();
print(foo); // Instance of 'Foo<SomeBaseClass>'
不可以用限定範圍的泛型參數,這樣靜態代碼檢查器將提示錯誤。
var foo = Foo<Object>();
Using generic methods 泛型方法
Initially, Dart’s generic support was limited to classes. A newer syntax, called generic methods, allows type arguments on methods and functions:
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;
}
下麵是允許使用泛型方法的場景:
In the function’s return type (T).
In the type of an argument (List