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
}

 

 

posted @ 2022-04-28 15:20  rogerwu  阅读(335)  评论(0编辑  收藏  举报