You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:51:57