Flutter---泛型
在 Dart 中,泛型(Generics)是一种强大的编程特性,它允许你编写可以处理多种数据类型的代码,同时保持类型安全。
当没有泛型的时候
// 只能存储字符串的列表
class StringList {List<String> items = [];void add(String item) {items.add(item);}String get(int index) {return items[index];}
}// 只能存储整数的列表
class IntList {List<int> items = [];void add(int item) {items.add(item);}int get(int index) {return items[index];}
}
// 需要为每种类型创建单独的类,代码重复!
使用泛型解决代码重复问题
// 通用的列表类,可以存储任何类型
class GenericList<T> {List<T> items = [];void add(T item) {items.add(item);}T get(int index) {return items[index];}
}void main() {// 存储字符串var stringList = GenericList<String>();stringList.add("Hello");stringList.add("World");print(stringList.get(0)); // 类型安全:知道返回的是String// 存储整数var intList = GenericList<int>();intList.add(1);intList.add(2);print(intList.get(0)); // 类型安全:知道返回的是int
}
语法理解
// T 是类型参数,可以是任何标识符
class ClassName<T> {T value;ClassName(this.value);T getValue() {return value;}
}// 多个类型参数
class Pair<K, V> {K key;V value;Pair(this.key, this.value);
}
泛型可以用于集合中List,Set和Map类型的参数化。对于List或Set,只需要在声明语句前添加类型前缀;对于Map,则需要在声明语句前添加<keyType,valueType>类型前缀。
1.List不用泛型
void main() {// 创建一个列表,但不指定类型List names = ['Alice', 'Bob', 'Charlie']; // 什么都能放names.add('David'); // ✅ 可以加字符串names.add(123); // ✅ 也可以加数字(但这样容易出错!)names.add(true); // ✅ 还可以加布尔值// 使用时不知道是什么类型,容易出错String firstPerson = names[0]; // ❌ 运行时可能出错,因为不知道names[0]是不是字符串print(firstPerson.toUpperCase()); // 如果names[0]是数字,这里就会崩溃!
}
List使用泛型
void main() {// 创建一个只能放字符串的列表List<String> names = ['Alice', 'Bob', 'Charlie'];names.add('David'); // ✅ 可以加字符串// names.add(123); // ❌ 编译时就报错!不能加数字// names.add(true); // ❌ 编译时就报错!不能加布尔值// 使用时很安全,知道一定是字符串String firstPerson = names[0]; // ✅ 安全,知道肯定是字符串print(firstPerson.toUpperCase()); // ✅ 不会出错
}
2.Map不使用泛型
void main() {// 创建一个Map,但不指定键值类型Map student = {'name': 'Alice','age': 20,'score': 95.5};student['height'] = 165; // ✅ 可以添加student[123] = 'test'; // ✅ 键可以是数字(混乱!)student['name'] = 999; // ✅ 把名字改成数字(不对!)// 使用时很困惑String name = student['name']; // ❌ 可能出错,因为name可能不是字符串int age = student['age']; // ❌ 可能出错
}
Map使用泛型
void main() {// 创建一个Map,键必须是字符串,值可以是任意类型Map<String, dynamic> student = {'name': 'Alice', // 值:字符串'age': 20, // 值:数字'score': 95.5 // 值:小数};student['height'] = 165; // ✅ 可以添加// student[123] = 'test'; // ❌ 编译错误!键必须是字符串// student['name'] = 999; // ❌ 编译错误!名字应该是字符串// 使用时很清楚String name = student['name']; // ✅ 安全int age = student['age']; // ✅ 安全
}
