文章目录

Dart 泛型:<T> 类型参数

发布于 2026-04-12 17:24:13 · 浏览 200 次 · 评论 0 条

Dart 泛型通过使用类型参数 <T>,让你能编写一套代码逻辑来处理多种数据类型,既保证了代码的复用性,又维持了严格的类型安全检查。以下指南将手把手教你如何在类、函数和集合中使用泛型。


1. 创建泛型类

编写一个通用的数据容器类,使其能够存储和返回任意类型的数据,而不需要为每种数据类型(如 int、String)都单独写一个类。

  1. 定义 一个名为 Box 的类。
  2. 在类名后添加 尖括号 <T>,将 T 声明为类型参数。
  3. 声明 一个类型为 T 的私有变量 _content。
  4. 编写 put 方法,接收类型为 T 的参数并赋值给 _content。
  5. 编写 get 方法,返回类型为 T 的 _content。
class Box {
  T _content;

  // 设置内容
  void put(T item) {
    _content = item;
  }

  // 获取内容
  T get() {
    return _content;
  }
}

2. 实例化与使用泛型类

在实际业务代码中,根据具体需求指定 <T> 的具体类型,或者利用 Dart 的类型推断机制。

  1. 创建 一个用于存储 String 类型的 Box 实例。
  2. 调用 put 方法,传入 字符串 "Hello Dart"。
  3. 调用 get 方法,将返回值赋值 给 String 类型的变量。
  4. 创建 一个用于存储 int 类型的 Box 实例。
  5. 调用 put 方法,传入 整数 100。
void main() {
  // 明确指定 <String>
  Box<String> stringBox = Box();
  stringBox.put("Hello Dart");
  String message = stringBox.get(); // 无需类型转换,安全

  // 利用类型推断,推断为 <int>
  var intBox = Box();
  intBox.put(100);
  int number = intBox.get();

  // 如果尝试存入错误类型,编译器会报错
  // intBox.put("Error"); // 报错:String 不能赋值给 int 参数
}

3. 使用泛型函数

当函数的逻辑与类型无关,但输入和输出的类型需要保持一致时,使用泛型函数。

  1. 定义 一个函数 firstItem,在函数名后的尖括号中声明 <T>。
  2. 设置 参数列表接收一个 List 类型的列表。
  3. 返回 列表的第一个元素,类型为 T。
  4. 在 main 函数中,传入 字符串列表和整数列表进行测试。
T firstItem(List list) {
  return list[0];
}

void main() {
  print(firstItem(["Apple", "Banana"])); // 输出: Apple
  print(firstItem([10, 20, 30]));        // 输出: 10
}

4. 限制泛型类型

有时你需要确保传入的类型参数 T 具有特定的功能(例如只能是比较数字,或者只能是某种类的子类)。使用 extends 关键字限制 T 的范围。

  1. 定义 一个类 NumberCache,限制 <T extends num>,意味着 T 只能是 int 或 double 及其子类。
  2. 声明 一个类型为 T 的变量 _value。
  3. 编写 add 方法,利用 num 类型的 + 操作符对数值进行运算。
  4. 尝试 在 main 中传入 int 和 String,观察结果。
class NumberCache {
  T _value;

  T add(T addend) {
    // 因为 T 限制为 num,所以可以直接使用 + 号
    return _value + addend as T;
  }
}

void main() {
  var intCache = NumberCache<int>();
  // intCache.add(10); // 正常运行

  // var strCache = NumberCache<String>(); // 报错:String 不是 num 的子类
}

5. 集合中的泛型应用

Dart 的核心集合(List、Set、Map)都是泛型类,合理使用它们能避免运行时错误。

  1. 定义 一个 List,显式声明 它包含 String 类型。
  2. 添加 字符串元素。
  3. 尝试 添加一个整数,观察编辑器的静态检查警告。
  4. 定义 一个 Map,规定 Key 为 String,Value 为 int。
特性 原始写法 泛型写法
类型声明 var names = []; List names = [];
类型安全 运行时可能崩溃 编译期即可发现错误
代码提示 无特定提示 自动补全 String 相关方法
void main() {
  // 定义字符串列表
  List<String> names = ["Alice", "Bob"];
  names.add("Charlie");

  // names.add(100); // 编译错误:int 类型无法添加到 String 列表中

  // 定义键值对 Map:Key是String,Value是int
  Map<String, int> scores = {
    "Math": 90,
    "English": 85,
  };

  scores["History"] = 95;
}

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文