泛型
例如基础数组类型,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).