// ❌ 编译错误:cannot use instanceof with generic type T
// if (list instanceof List<String>) { }
// ❌ 无法创建泛型数组
// T[] array = new T[10];
Dart 的具化泛型(Reified Generics)
Dart 在运行时完整保留类型信息:
void main() {
var strings = <String>[];
var integers = <int>[];
// 运行时可以区分泛型类型!
print(strings.runtimeType); // List<String>
print(integers.runtimeType); // List<int>
print(strings is List<String>); // true
print(strings is List<int>); // false ← 运行时检查!
// 可以比较类型
print(strings.runtimeType == integers.runtimeType); // false
}
// 泛型类型在运行时的意义
void checkType<T>(T value) {
if (T == String) {
print('这是一个字符串: $value');
} else if (T == int) {
print('这是一个整数: $value');
}
// 或者用 is
if (value is String) {
print('字符串长度: ${value.length}');
}
}
// 获取泛型类型对象
Type getType<T>() => T;
void main2() {
Type stringType = getType<String>();
Type intType = getType<int>();
print(stringType); // String
print(stringType == String); // true
}
2. 泛型约束与上界
2.1 单上界约束(extends)
// T 必须是 num 或其子类(int、double)
T max<T extends num>(T a, T b) => a > b ? a : b;
void main() {
print(max(3, 5)); // 5(int)
print(max(3.14, 2.72)); // 3.14(double)
// max('a', 'b'); // ❌ 编译错误:String 不是 num 的子类
}
// 泛型类的约束
class SortedList<T extends Comparable<T>> {
final List<T> _items = [];
void add(T item) {
_items.add(item);
_items.sort(); // 可以调用 sort,因为 T 实现了 Comparable
}
T get max => _items.last;
T get min => _items.first;
List<T> get items => List.unmodifiable(_items);
}
// 使用
final numbers = SortedList<int>()..add(3)..add(1)..add(2);
print(numbers.items); // [1, 2, 3]
print(numbers.max); // 3
// ❌ 编译错误:Object 没有实现 Comparable
// final objects = SortedList<Object>();
2.2 多约束(通过 Mixin 实现)
// Dart 不支持多上界(如 Java 的 T extends A & B),但可以通过接口组合解决
abstract interface class Saveable {
Future<void> save();
}
abstract interface class Validatable {
bool validate();
}
// 组合接口
abstract interface class Entity implements Saveable, Validatable {
int get id;
}
// T 必须实现 Entity(因此也实现了 Saveable 和 Validatable)
Future<void> saveIfValid<T extends Entity>(T entity) async {
if (entity.validate()) {
await entity.save();
print('Entity ${entity.id} 已保存');
} else {
print('Entity ${entity.id} 验证失败,跳过保存');
}
}
3. 协变、逆变与不变
3.1 Dart 的协变规则
// ⚠️ Dart 的 List 是协变的(Covariant),但这会导致运行时错误
void covariantTrap() {
List<int> ints = [1, 2, 3];
List<num> nums = ints; // ✅ 编译通过(List<int> 是 List<num> 的子类型)
// ❌ 运行时错误!ints 实际上是 List<int>,不能添加 double
nums.add(3.14); // throws: TypeError: 3.14 is not a subtype of int
}
// 安全的协变:只读集合
List<num> safeCovariant(List<int> ints) {
// List<int> 赋值给 List<num> 是安全的,前提是只读
return List<num>.unmodifiable(ints);
}
// 泛型函数
T identity<T>(T value) => value;
// 类型参数自动推断
var s = identity('hello'); // T 推断为 String
var n = identity(42); // T 推断为 int
// 多类型参数
MapEntry<K, V> pair<K, V>(K key, V value) => MapEntry(key, value);
// 泛型函数作为高阶函数
List<R> mapList<T, R>(List<T> list, R Function(T) transform) {
return list.map(transform).toList();
}
var lengths = mapList(['hello', 'world'], (s) => s.length); // List<int>
4.2 类型推断的边界
// Dart 的类型推断是局部的(Local Type Inference)
// ✅ 可以推断
var result = [1, 2, 3].map((x) => x * 2).toList(); // List<int>
// ⚠️ 推断失败时需要显式标注
var mixed = []; // List<dynamic>!
var typed = <int>[]; // ✅ 明确类型
// 泛型方法调用时的类型参数传递
// ✅ 可以推断:
final list = List.generate(5, (i) => i.toString()); // List<String>
// ⚠️ 某些情况必须显式传递类型参数
abstract class JsonParser<T> {
T parse(Map<String, dynamic> json);
}
T parseJson<T>(Map<String, dynamic> json, JsonParser<T> parser) {
return parser.parse(json);
}
// 调用时如果无法推断,需要显式指定
// final user = parseJson(json, UserParser()); // 推断为 User
4.3 泛型的运行时行为
// 泛型类的工厂构造函数
abstract class Serializable {
Map<String, dynamic> toJson();
}
class TypedList<T extends Serializable> {
final List<T> _items;
TypedList(this._items);
// 运行时获取元素类型
Type get elementType => T;
List<Map<String, dynamic>> serialize() {
return _items.map((item) => item.toJson()).toList();
}
// 用泛型创建特定类型的空列表
TypedList<T> empty() => TypedList<T>([]);
}
5. 运行时类型反射
// Type 对象
void reflectType<T>() {
final type = T; // 获取 Type 对象
print('类型名: $type');
print('是否为 String: ${type == String}');
print('是否为 int: ${type == int}');
}
// 工厂注册表(Registry Pattern)
class Registry<T> {
final Map<Type, T Function()> _factories = {};
void register<S extends T>(S Function() factory) {
_factories[S] = factory;
}
T? create<S extends T>() {
final factory = _factories[S];
return factory?.call();
}
bool hasType<S>() => _factories.containsKey(S);
}
// 使用
void main() {
final registry = Registry<Widget>();
registry.register<Button>(() => Button());
registry.register<TextField>(() => TextField());
final btn = registry.create<Button>(); // 返回 Button 实例
print(registry.hasType<Image>()); // false
}
// 类型安全的事件总线
class TypedEventBus {
final Map<Type, List<Function>> _handlers = {};
void on<T>(void Function(T event) handler) {
_handlers.putIfAbsent(T, () => []).add(handler);
}
void emit<T>(T event) {
final handlers = _handlers[T];
if (handlers != null) {
for (final handler in handlers) {
(handler as void Function(T))(event);
}
}
}
void off<T>(void Function(T event) handler) {
_handlers[T]?.remove(handler);
}
}
// 使用事件总线
class UserLoggedInEvent {
final String username;
UserLoggedInEvent(this.username);
}
void setupEventHandlers(TypedEventBus bus) {
bus.on<UserLoggedInEvent>((event) {
print('用户登录: ${event.username}');
});
bus.emit(UserLoggedInEvent('Alice')); // 触发事件
}
6. 类型安全的容器设计
// Result<T, E>:类型安全的错误处理
sealed class Result<T, E extends Exception> {
const Result();
bool get isSuccess => this is Ok<T, E>;
bool get isFailure => this is Err<T, E>;
T get valueOrThrow => switch (this) {
Ok(:final value) => value,
Err(:final error) => throw error,
};
T valueOr(T defaultValue) => switch (this) {
Ok(:final value) => value,
Err() => defaultValue,
};
Result<R, E> map<R>(R Function(T) transform) => switch (this) {
Ok(:final value) => Ok(transform(value)),
Err(:final error) => Err(error),
};
Result<R, E> flatMap<R>(Result<R, E> Function(T) transform) => switch (this) {
Ok(:final value) => transform(value),
Err(:final error) => Err(error),
};
void when({
required void Function(T value) ok,
required void Function(E error) err,
}) {
switch (this) {
case Ok(:final value): ok(value);
case Err(:final error): err(error);
}
}
}
final class Ok<T, E extends Exception> extends Result<T, E> {
final T value;
const Ok(this.value);
@override
String toString() => 'Ok($value)';
}
final class Err<T, E extends Exception> extends Result<T, E> {
final E error;
const Err(this.error);
@override
String toString() => 'Err($error)';
}
// 使用示例
Future<Result<User, NetworkException>> fetchUser(int id) async {
try {
final data = await api.get('/users/$id');
return Ok(User.fromJson(data));
} on NetworkException catch (e) {
return Err(e);
}
}
void handleUser(int id) async {
final result = await fetchUser(id);
result.when(
ok: (user) => print('欢迎 ${user.name}'),
err: (e) => print('错误: $e'),
);
// 链式操作
final greeting = (await fetchUser(id))
.map((user) => user.name)
.map((name) => '欢迎 $name')
.valueOr('获取失败');
}
7. 与 Java / TypeScript / Kotlin 的对比
Java 泛型的局限
// Java:无法在运行时获取泛型类型publicclassContainer<T> {
private T value;
// ❌ 编译错误:无法创建泛型数组// private T[] array = new T[10];// ❌ 编译错误:不能用 instanceof 检查泛型// if (value instanceof T) { }// ❌ 无法直接获取 T 的 Class 对象// Class<T> type = T.class; // 错误!// 绕过方案:传入 Class<T>("类型令牌")publicstatic <T> Container<T> of(Class<T> type, Object raw) {
returnnewContainer<>(type.cast(raw));
}
}
TypeScript 的条件类型
// TypeScript 支持条件类型(Dart 没有等价特性)typeNonNullable<T> = T extendsnull | undefined ? never : T;
typeReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
// TypeScript 的 infer(Dart 无等价)typeUnwrap<T> = T extendsPromise<infer U> ? U : T;
typeUnwrappedString = Unwrap<Promise<string>>; // string
Kotlin 泛型
// Kotlin:inline reified 泛型(类似 Dart,但更强大)inlinefun<reified T>isType(value: Any): Boolean {
return value is T // ✅ 运行时可以检查!(因为 reified)
}
// Kotlin:out/in(协变/逆变标注)classProducer<out T>(privateval value: T) {
funget(): T = value
}
classConsumer<in T> {
funaccept(value: T) { println(value) }
}
val producer: Producer<Number> = Producer<Int>(42) // ✅ 协变
8. 实战案例:类型安全的依赖注入容器
// 简化的类型安全依赖注入容器
class Container {
final Map<_ServiceKey, dynamic> _singletons = {};
final Map<_ServiceKey, dynamic Function(Container)> _factories = {};
// 注册单例
void singleton<T>(T instance, {String? name}) {
_singletons[_ServiceKey(T, name)] = instance;
}
// 注册工厂(每次创建新实例)
void factory<T>(T Function(Container c) builder, {String? name}) {
_factories[_ServiceKey(T, name)] = builder;
}
// 注册懒加载单例
void lazySingleton<T>(T Function(Container c) builder, {String? name}) {
final key = _ServiceKey(T, name);
_factories[key] = (c) {
if (!_singletons.containsKey(key)) {
_singletons[key] = builder(c);
}
return _singletons[key];
};
}
// 解析依赖
T resolve<T>({String? name}) {
final key = _ServiceKey(T, name);
// 先查单例
if (_singletons.containsKey(key)) {
return _singletons[key] as T;
}
// 再查工厂
final factory = _factories[key];
if (factory != null) {
return factory(this) as T;
}
throw StateError('没有注册类型 $T${name != null ? ' (name: $name)' : ''}');
}
T call<T>({String? name}) => resolve<T>(name: name);
}
class _ServiceKey {
final Type type;
final String? name;
_ServiceKey(this.type, this.name);
@override
bool operator ==(Object other) =>
other is _ServiceKey && type == other.type && name == other.name;
@override
int get hashCode => Object.hash(type, name);
}
// 使用示例
void setupContainer() {
final container = Container();
// 注册基础设施
container.singleton<Database>(Database('postgresql://localhost/mydb'));
container.singleton<HttpClient>(HttpClient(baseUrl: 'https://api.example.com'));
// 注册仓库层(懒加载)
container.lazySingleton<UserRepository>(
(c) => UserRepository(c<Database>()),
);
container.lazySingleton<ProductRepository>(
(c) => ProductRepository(c<Database>(), c<HttpClient>()),
);
// 注册服务层
container.lazySingleton<UserService>(
(c) => UserService(c<UserRepository>()),
);
// 工厂:每次请求创建新的 RequestContext
container.factory<RequestContext>(
(c) => RequestContext(c<UserService>()),
);
// 使用
final userService = container<UserService>();
final ctx1 = container<RequestContext>(); // 新实例
final ctx2 = container<RequestContext>(); // 另一个新实例
print(identical(ctx1, ctx2)); // false(工厂)
print(identical(
container<UserService>(),
container<UserService>(),
)); // true(懒加载单例)
}