为何Dart泛型不使用实例实际类型,而是沿用List泛型?
Dart泛型类型推断疑问解析
定义的Dart类
class Class<T extends num> { const Class(this.n); final T n; @override String toString() { return 'Class<$T>(n: $n<${n.runtimeType}>)'; } }
运行代码
for (final n in <num>[0.3, 2, -4]) { final instance = Class(n); print('$instance'); } final instance = Class(1); print('$instance');
输出结果
Class<num>(n: 0.3<double>) Class<num>(n: 2<int>) Class<num>(n: -4<int>) Class<int>(n: 1<int>)
疑问
为何Dart不使用数值的实际类型确定泛型参数,而是采用List的泛型类型num?
解析
- Dart的类型推断依赖静态类型,而非运行时的实际类型。当你显式声明
<num>[0.3, 2, -4]时,这个List的静态类型被固定为List<num>,遍历出的每个元素n的静态类型也随之确定为num,不管它实际存储的是double还是int。 - 调用
Class(n)时,Dart会根据n的静态类型推断泛型参数T。因为n的静态类型是num,所以T被推断为num,这就出现了输出里Class<num>的结果。 - 单独调用
Class(1)时,1的静态类型就是int,没有被上层容器的类型约束,所以泛型参数T直接被推断为int,和运行时类型一致。 - 本质上,Dart在编译阶段就确定了泛型参数,它只看变量在编译期的静态类型声明,不会等到运行时去识别实际存储的类型。List被声明为
num类型后,内部元素的静态类型被统一约束,泛型推断自然沿用这个类型。
内容的提问来源于stack exchange,提问作者FMorschel
相关产品推荐
相关产品推荐

