问什么使用泛型

  • 类型安全
  • 生成更好的代码
  • 减少代码重复

编译时能够检测出错误:

  1. var names = List<String>();
  2. names.addAll(['Seth', 'Kathy', 'Lars']);
  3. names.add(42); // Error

静态分析:

  1. abstract class ObjectCache {
  2. Object getByKey(String key);
  3. void setByKey(String key, Object value);
  4. }
  5. // 不使用泛型, 可能需要对其它类型进行定义, 比如 int
  6. abstract class StringCache {
  7. String getByKey(String key);
  8. void setByKey(String key, String value);
  9. }
  10. // 使用泛型, 减少接口定义
  11. abstract class Cache<T> {
  12. T getByKey(String key);
  13. void setByKey(String key, T value);
  14. }

使用集合字面量

  1. var names = <String>['Seth', 'Kathy', 'Lars'];
  2. var uniqueNames = <String>{'Seth', 'Kathy', 'Lars'};
  3. var pages = <String, String>{
  4. 'index.html': 'Homepage',
  5. 'robots.txt': 'Hints for web robots',
  6. 'humans.txt': 'We are people, not machines'
  7. };

使用带有构造器的参数化类型

  1. var nameSet = Set<String>.from(names);
  2. var views = Map<int, View>();

泛型集合和它们的类型

泛型集合在运行时携带类型信息:

  1. var names = List<String>();
  2. names.addAll(['Seth', 'Kathy', 'Lars']);
  3. print(names is List<String>); // true

限制参数化类型

  1. class Foo<T extends SomeBaseClass> {
  2. // Implementation goes here...
  3. String toString() => "Instance of 'Foo<$T>'";
  4. }
  5. class Extender extends SomeBaseClass {...}
  6. // 使用
  7. var someBaseClassFoo = Foo<SomeBaseClass>();
  8. var extenderFoo = Foo<Extender>();
  9. // 不指定具体父类
  10. var foo = Foo();
  11. print(foo); // Instance of 'Foo<SomeBaseClass>'

使用泛型方法

  1. T first<T>(List<T> ts) {
  2. // Do some initial work or error checking, then...
  3. T tmp = ts[0];
  4. // Do some additional checking or processing...
  5. return tmp;
  6. }