flutter中泛型<T>

220 阅读2分钟

在 Dart 中,泛型(Generics)允许你编写灵活且可重用的代码,特别是在处理集合类时。使用泛型,可以让类、方法、接口等接受类型参数,从而增强类型安全性。

1. 泛型的基本用法

泛型的基本语法是使用尖括号 <T>,其中 T 是一个类型参数。可以为 T 选择任何有效的类型名称。

示例:定义一个泛型类
class Box<T> {
  T? content;

  Box(this.content);

  T? getContent() {
    return content;
  }
}

void main() {
  var intBox = Box<int>(123);
  print(intBox.getContent()); // 输出: 123

  var stringBox = Box<String>('Hello');
  print(stringBox.getContent()); // 输出: Hello
}

在这个例子中,Box 是一个泛型类,它可以存储任何类型的内容。

2. 泛型方法

除了泛型类外,也定义泛型方法。方法的泛型类型参数可以与类的类型参数不同。

示例:定义一个泛型方法
T identity<T>(T value) {
  return value;
}

void main() {
  print(identity<int>(42)); // 输出: 42
  print(identity<String>('Hello')); // 输出: Hello
}

3. 约束泛型类型

限制泛型类型参数的类型,可以通过 extends 关键字来实现。

示例:约束泛型类型
class ComparableBox<T extends Comparable> {
  T content;

  ComparableBox(this.content);

  bool isGreaterThan(T other) {
    return content.compareTo(other) > 0;
  }
}

void main() {
  var box1 = ComparableBox<int>(10);
  var box2 = ComparableBox<int>(5);
  print(box1.isGreaterThan(box2.content)); // 输出: true
}

在这个例子中,T 被约束为实现 Comparable 接口的类型。

4. 泛型集合

Dart 的集合类(如 List, Set, Map)也使用了泛型,可以指定集合中元素的类型。

示例:使用泛型集合
void main() {
  List<int> numbers = [1, 2, 3];
  Set<String> names = {'Alice', 'Bob'};
  Map<String, int> ages = {'Alice': 30, 'Bob': 25};

  print(numbers); // 输出: [1, 2, 3]
  print(names); // 输出: {Alice, Bob}
  print(ages); // 输出: {Alice: 30, Bob: 25}
}

5. 可空类型与泛型

Dart 的 null-safety 特性与泛型一起使用时也很重要。使用 T? 表示一个可空的泛型类型。

示例:可空泛型
class NullableBox<T> {
  T? content;

  NullableBox(this.content);
}

void main() {
  var box = NullableBox<int?>(null);
  print(box.content); // 输出: null
}

6. 泛型的实际应用

  • 数据结构:泛型在实现自定义的数据结构(如栈、队列、链表等)时非常有用。
  • API 设计:当设计 API 时,使用泛型可以使 API 更加灵活和可重用。
  • 状态管理:在 Flutter 中,使用泛型可以简化状态管理,确保类型安全。