为何Dart无法在重定向构造函数中推断类型?
问题解析:重定向构造函数中传入Child为何触发编译错误
最小复现代码
class Parent {} class Child extends Parent {} class Foo<T extends Parent> { final T t; Foo(this.t); Foo.one(Child child) : this(child); // 编译错误 }
错误提示:参数类型“Child”无法分配给参数类型“T”。
核心原因
Dart泛型的类型检查基于调用上下文的泛型参数绑定,而非参数的实际类型推导:
- 泛型类
Foo<T>的所有构造函数(包括重定向构造)共享同一个泛型参数T,这个T的具体类型由调用构造时的外部代码上下文决定,不是构造函数内部能自行推导的。 - 在
Foo.one(Child child)这个重定向构造中,调用this(child)时,Dart无法保证传入的Child实例一定符合当前绑定的T类型:比如如果存在另一个子类OtherChild extends Parent,当外部调用Foo<OtherChild>.one(Child())时,T被绑定为OtherChild,但Child并非OtherChild的子类,这会直接破坏类型安全。 - 而
main函数中的Foo(Child())能正常运行,是因为这里触发了Dart的隐式类型推导:没有显式指定T时,Dart会根据传入的Child实例自动将T推导为Child,此时参数类型和T完全匹配,因此合法。
本质上,重定向构造里的T是“外部指定”的,Dart必须确保无论外部指定什么合法的T(只要是Parent的子类),构造逻辑都不会违反类型安全,而传入固定的Child显然无法满足这个要求。
内容的提问来源于stack exchange,提问作者iDecode
相关产品推荐
相关产品推荐

