Dart 泛型

2023/6/2

# Dart 泛型

泛型是在函数、类、接口中指定 宽泛数据类型 的语法。

通常,在尖括号中,使用一个字母来代表类型,类如 E T S K 和 V 等。

返回类型 函数名<输入类型>(参数类型 参数) {
    函数体
}
1
2
3

使用泛型可以帮我们减少重复的代码。我现在通过一个函数就可以替代多个需要明确数据类型的函数。 20230602154551

泛型的类型传递过程: 20230602154420

# 泛型函数

// String getData(String value) {
//   return value;
// }

// int getData(int value) {
//   return value;
// }

// 不指定数据类型的函数
// getData(value) {
//   return value;
// }

T getData<T>(T value) {
  return value;
}

// 只约定参数类型,不约定函数返回值的类型
// getData<T>(T value) {
//   return value;
// }

void main() {
  // print(getData(1));

  // 调用泛型函数
  print(getData<int>(20));

  print(getData<String>('Hello'));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 泛型类

class CommonClass {
  Set s = new Set<int>();

  void add(int value) {
    this.s.add(value);
  }

  void info() {
    print(this.s);
  }
}

// 泛型类
class GenericsClass<T> {
  Set s = new Set<T>();

  void add(T value) {
    this.s.add(value);
  }

  void info() {
    print(this.s);
  }
}

void main() {
  CommonClass c = new CommonClass();
  c.add(1);
  c.add(2);
  c.info();

  // 实例化泛型类
  GenericsClass g = new GenericsClass<int>();
  g.add(1);
  g.add(2);
  g.info();

  GenericsClass g1 = new GenericsClass<String>();
  g1.add('Hello');
  g1.add('World');
  g1.info();

  // Set s = new Set();
  // s.add(1);
  // s.add('hello');
  // print(s);

  // Set s = new Set<int>();
  // s.add(1);
  // s.add('hello'); // 运行时报错
  // s.add(3);
  // print(s);

  // 字面量形式的泛型
  Set s = <int>{};
  s.add(1);
  // s.add('hello'); // 运行时报错
  s.add(3);
  print(s);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

# 泛型接口

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

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

// 泛型接口
abstract class Cache<T> {
  getByKey(String key);
  void setByKey(String key, T value);
}

// 文件缓存
class FileCache<T> implements Cache<T> {
  
  getByKey(String key) {
    return null;
  }

  
  void setByKey(String key, T value) {
    print('文件缓存: key=${key} value=${value}');
  }
}

// 内存缓存
class MemoryCache<T> implements Cache<T> {
  
  getByKey(String key) {
    return null;
  }

  
  void setByKey(String key, T value) {
    print('内存缓存: key=${key} value=${value}');
  }
}

void main() {
  // 文件缓存 - 缓存字符串
  // FileCache fc = new FileCache<String>();
  // fc.setByKey('foo', 'bar');
  // fc.setByKey('foo', 2); // 运行时报错

  // 文件缓存 - 缓存 Map
  FileCache fc = new FileCache<Map>();
  fc.setByKey('index', {"name": "张三丰", "age": 129});

  // 内存缓存 - 缓存字符串
  // MemoryCache mc = new MemoryCache<String>();
  // mc.setByKey('foo', 'bar');

  // 内存缓存 - 缓存集合
  MemoryCache mc = new MemoryCache<Set>();
  mc.setByKey('home', {1, 2, 3});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

# 泛型类型限制

class SomeBaseClass {
  // ...
}

class Foo<T extends SomeBaseClass> {
  String toString() => "Instance of 'Foo<$T>'";
}

// 子类
class Extender extends SomeBaseClass {
  // ...
}

class AnotherClass {
  // ...
}

void main() {
  var someBaseClass = Foo<SomeBaseClass>();
  print(someBaseClass); // Instance of 'Foo<SomeBaseClass>'

  var extenderFoo = Foo<Extender>();
  print(extenderFoo); // Instance of 'Foo<Extender>'

  var foo = Foo();
  print(foo); // Instance of 'Foo<SomeBaseClass>'

  // var f = Foo<AnotherClass>(); // 类型不对
  // print(f);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30