Dart 泛型和枚举
泛型
泛型是在函数、类、接口中指定宽泛数据类型的语法
- 泛型函数
- 泛型类
- 泛型接口
通常,在尖括号中,使用一个字母来代表类型,例如:E,T,S,K,V等,格式如下:
返回类型 函数名 <输入类型>(参数类型 参数) {
函数体
}
作用:使用泛型可以减少重复的代码
泛型函数
// 泛型函数 T getData<T>(T value) { return value; } void main() { // 调用泛型函数 String str = getData<String>('hello world'); int age = getData<int>(18); print(str); // hello print(age); // 18 }
// 只约定参数类型,不约定函数返回值的类型 getInfo<T>(T value) { return value; }
泛型类
// 泛型类 class GenericsClass<T> { Set s = new Set<T>(); void add(T value) { this.s.add(value); } void info() { print(this.s); } } void main() { // 实例化泛型类 GenericsClass g1 = new GenericsClass<int>(); g1.add(1); g1.add(2); // g1.add('string'); // Error: type 'String' is not a subtype of type 'int' of 'value' g1.info(); // {1, 2} GenericsClass g2 = new GenericsClass<String>(); g2.add('apple'); g2.add('pear'); g2.info(); // {apple, pear} }
泛型接口
// 泛型接口 abstract class Cache<T> { getByKey(String key); void setByKey(String key, T value); } // 文件缓存 class FileCache<T> implements Cache<T> { @override getByKey(String key) { return null; } @override void setByKey(String key, T value) { print('文件缓存:key = ${key} value = ${value}'); } } // 内存缓存 class MemoryCache<T> implements Cache<T> { @override getByKey(String key) { return null; } @override void setByKey(String key, T value) { print('内存缓存:key = ${key} value = ${value}'); } } void main() { // 文件缓存 - 缓存字符串 FileCache fc = new FileCache<String>(); fc.setByKey('name', 'Peter Parker'); // fc.setByKey('age', 24); // Error: type 'int' is not a subtype of type 'String' of 'value' // 文件缓存 - 缓存Map FileCache fm = new FileCache<Map>(); fm.setByKey('userInfo', {'name': 'Iron Man', 'age': 40}); // 内存缓存 - 缓存集合 MemoryCache mc = new MemoryCache<Set>(); mc.setByKey('fruits', {'apple', 'orange', 'banana'}); }
泛型约束
class Base { // ... } class Separate { // ... } // 泛型约束 class Sub<T extends Base> { String getInfo() => 'Instance of Sub<$T>'; } void main() { Sub s = new Sub<Base>(); print(s.getInfo()); // Instance of Sub<Base> // 报错:类型不对 Sub a = new Sub<Separate>(); // 'Separate' doesn't conform to the bound 'Base' of the type parameter 'T'. }
// 子类 class Child extends Base { // ... } // 泛型约束 class Sub<T extends Base> { String getInfo() => 'Instance of Sub<$T>'; } void main() { Sub c = new Sub<Child>(); print(c.getInfo()); // Instance of Sub<Child> Sub empty = new Sub(); print(empty.getInfo()); // Instance of Sub<Base> }
// 泛型约束示例 T plus<T extends num>(T a, T b) { return a + b; } void main() { int result1 = plus(3, 5); double result2 = plus(2.45, 4.566); // String result3 = plus('flu', 'tter'); // Error: type 'String' is not a subtype of type 'Never' print(result1); // 8 print(result2); // 7.016 }
枚举
枚举是数量固定的常量值,通过 enum 关键字声明
enum Color { red, green, blue }
枚举的 values 常量,可以获取所有枚举值列表
List<Color> colors = Color.values;
可以通过 index 获取值的索引
assert(Color.green.index == 1);
enum Color { red, green, blue } void main() { // 通过 index 返回枚举中具体常量的值 print(Color.green.index); // 1 print(Color.green.name); // green // 通过 values 返回常量列表 print(Color.values); // [Color.red, Color.green, Color.blue] print(Color.green); // Color.green List<Color> colors = Color.values; print(colors); // [Color.red, Color.green, Color.blue] // 通过下标访问列表中的内容 print(Color.values[2]); // Color.blue // print(Color.values[3]); // Error: Invalid value: Not in inclusive range 0..2: 3 // 通过 forEach 遍历列表中的内容 colors.forEach((element) { print('value: $element, index: ${element.index}'); }); // value: Color.red, index: 0 // value: Color.green, index: 1 // value: Color.blue, index: 2 }