带你Dart带你Diao之泛型
2018-12-22 本文已影响4人
树獭非懒
泛型学过Java的都应该比较熟悉了,Dart的泛型和Java泛型的核心理念都差不多,在使用中略有不同。
1.使用泛型的好处
泛型通常是类型安全所必需的,对于写出严谨高质量的代码是很有用
- 适当地指定泛型类型可以生成更好的代码
- 使用泛型可以减少重复的代码量
举两个栗子
1.添加不是所定义的泛型类型的值时,编译器直接提醒报错
var names = List<String>();
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>{
T getByKey();
void setByKey(String key,T value);
}
实现这个接口时把T定义成你想要的类型,String、int...
比如实现上面的接口,并把T设为int,会发现实现接口的方法的参数中的T变成了int类型
class StringCache implements GenericCache<int>{
@override
int getByKey() {
// TODO: implement getByKey
return null;
}
@override
void setByKey(String key, int value) {
// TODO: implement setByKey
}
}
通过这种方法,可以大大减少重复代码的量
二、集合字面量
List和map字面量可以被参数化。参数化字面量和你已经认识的所有字面量一样,仅仅是在字面量的开始括号之前添加<type>(对于list类型来说)或者添加<keyType, valueType>(对于map类型来说)
var names=<String>['a','b','c']; //为List指定类型
var pages=<String,String>{ //为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<T extends StringCache> {
// 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<StringCache>'
var someBaseFoo=Foo<Extender>(); //T只能定义成 继承StringCache的子类,其他则会报错
print(someBaseFoo); //打印出 Instance of 'Foo<Extender>'
}
四、泛型方法
还是举个栗子
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;
}
调用这个方法
var ts=<String>['a','b','c'];
//int res=first(ts); 编译报错 ts是String类型,不能转换成int
String res=first(ts);
print(res[0]); //输出 a
first方法上泛型参数(<T>)允许你在很多地方使用类型参数T:
- 在函数的返回中返回类型(T)
- 在参数的类型中使用(List<T>)
- 在局部变量的类型中(T tmp)
五、一个很不同的地方
测试集合的类型的时候。在java中,泛型在运行时就会被擦除,所以在Java中是不能判断出一个对象是List<String>,只能判断出它的一个List集合。但是在dart里,是可以判断出它是不是List<String>,
比如下面的栗子它会打印出true
var names=<String>['a','b','c']; //为List指定类型
print(names is List<String>); //true