带你Dart带你Diao之泛型

泛型学过Java的都应该比较熟悉了,Dart的泛型和Java泛型的核心理念都差不多,在使用中略有不同。

1.使用泛型的好处

泛型通常是类型安全所必需的,对于写出严谨高质量的代码是很有用

  • 适当地指定泛型类型可以生成更好的代码
  • 使用泛型可以减少重复的代码量

举两个栗子

1.添加不是所定义的泛型类型的值时,编译器直接提醒报错
  var names = List();
  names.addAll(['Seth', 'Kathy', 'Lars']);
  //names.add(42); //编译时就会报错,只可以添加
2.减少代码重复量

比如定义一个接口ObjectCache

abstract class ObjectCache {
   Object getByKey(String key);
   void setByKey(String key,Object value);
}

实现这个接口后,我们的参数值只能是String类型,如果想换成int只能重新定义一个接口

但是使用泛型后,可以写出这样

abstract class GenericCache{
  T getByKey();
  void setByKey(String key,T value);
}

实现这个接口时把T定义成你想要的类型,String、int...

比如实现上面的接口,并把T设为int,会发现实现接口的方法的参数中的T变成了int类型


class StringCache implements GenericCache{
  @override
  int getByKey() {
    // TODO: implement getByKey
    return null;
  }

  @override
  void setByKey(String key, int value) {
    // TODO: implement setByKey
  }
}

通过这种方法,可以大大减少重复代码的量

二、集合字面量

List和map字面量可以被参数化。参数化字面量和你已经认识的所有字面量一样,仅仅是在字面量的开始括号之前添加(对于list类型来说)或者添加(对于map类型来说)

 var names=['a','b','c'];  //为List指定类型
   var pages={         //为Map的key和value分别指定类型
     'index.html': 'Homepage',
    'robots.txt': 'Hints for web robots',
    'humans.txt': 'We are people, not machines'
   };

  //names.add(1); //编译报错,因为添加的是非String
  names.add('d');  //true

三、限制参数的类型

在实现泛型类型时,您可能希望限制其参数的类型。你可以使用extends

定义两个类

class Foo {
  // Implementation goes here...
  String toString() => "Instance of 'Foo<$T>'";
}
class Extender extends StringCache {
    String toString() => "Instance of Extender";
}

使用这两个类

void limitParameterized(){
    var foo=Foo();
    print(foo);      //打印出 Instance of 'Foo'
    
    var someBaseFoo=Foo(); //T只能定义成 继承StringCache的子类,其他则会报错
    print(someBaseFoo);  //打印出 Instance of 'Foo'
}

四、泛型方法

还是举个栗子

T first(List ts) {
  // Do some initial work or error checking, then...
  T tmp = ts[0];
  // Do some additional checking or processing...
  return tmp;
}

调用这个方法

 var ts=['a','b','c']; 
 //int res=first(ts);  编译报错 ts是String类型,不能转换成int
 String res=first(ts); 
 print(res[0]);  //输出 a

first方法上泛型参数()允许你在很多地方使用类型参数T:

  • 在函数的返回中返回类型(T)
  • 在参数的类型中使用(List)
  • 在局部变量的类型中(T tmp)

五、一个很不同的地方

测试集合的类型的时候。在java中,泛型在运行时就会被擦除,所以在Java中是不能判断出一个对象是List,只能判断出它的一个List集合。但是在dart里,是可以判断出它是不是List

比如下面的栗子它会打印出true

var names=['a','b','c'];  //为List指定类型
print(names is List);  //true

你可能感兴趣的:(带你Dart带你Diao之泛型)