Dart 泛型通过使用类型参数 <T>,让你能编写一套代码逻辑来处理多种数据类型,既保证了代码的复用性,又维持了严格的类型安全检查。以下指南将手把手教你如何在类、函数和集合中使用泛型。
1. 创建泛型类
编写一个通用的数据容器类,使其能够存储和返回任意类型的数据,而不需要为每种数据类型(如 int、String)都单独写一个类。
- 定义 一个名为
Box的类。 - 在类名后添加 尖括号
<T>,将T声明为类型参数。 - 声明 一个类型为
T的私有变量_content。 - 编写
put方法,接收类型为T的参数并赋值给_content。 - 编写
get方法,返回类型为T的_content。
class Box {
T _content;
// 设置内容
void put(T item) {
_content = item;
}
// 获取内容
T get() {
return _content;
}
}
2. 实例化与使用泛型类
在实际业务代码中,根据具体需求指定 <T> 的具体类型,或者利用 Dart 的类型推断机制。
- 创建 一个用于存储
String类型的Box实例。 - 调用
put方法,传入 字符串"Hello Dart"。 - 调用
get方法,将返回值赋值 给String类型的变量。 - 创建 一个用于存储
int类型的Box实例。 - 调用
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. 使用泛型函数
当函数的逻辑与类型无关,但输入和输出的类型需要保持一致时,使用泛型函数。
- 定义 一个函数
firstItem,在函数名后的尖括号中声明<T>。 - 设置 参数列表接收一个
List类型的列表。 - 返回 列表的第一个元素,类型为
T。 - 在
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 的范围。
- 定义 一个类
NumberCache,限制<T extends num>,意味着T只能是int或double及其子类。 - 声明 一个类型为
T的变量_value。 - 编写
add方法,利用num类型的+操作符对数值进行运算。 - 尝试 在
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)都是泛型类,合理使用它们能避免运行时错误。
- 定义 一个
List,显式声明 它包含String类型。 - 添加 字符串元素。
- 尝试 添加一个整数,观察编辑器的静态检查警告。
- 定义 一个
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;
}
暂无评论,快来抢沙发吧!