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

Dart泛型类型检查:为何`a is B`不触发类型提升而`a is B<int>`可以?

Dart泛型类型检查的类型推断差异解析

代码示例

class A<T> {
  const A(this.value);
  final T value;
}

class B<T> extends A<T> {
  const B(super.value);
  
  T get getter => value;
}

void main() {
  final A<int> a = B<int>(2);
  
  if (a is B) {
    a.getter;  // <- Lint: The getter 'getter' isn't defined for the type 'A<int>'.
    // Work if I do:
    // (a as B).getter;
  }
  if (a is B<int>) {
    a.getter;
  }
}

问题现象

变量a声明为A<int>类型,实际指向B<int>实例:

  • 使用if (a is B)检查时,分支内的a仍保持A<int>类型,调用getter会触发语法检查错误,必须显式用as转换才能调用;
  • 使用if (a is B<int>)检查时,分支内的a会自动被推断为B<int>类型,可直接调用getter。

差异原因

这是Dart类型系统的设计规则导致的:

  • 原始类型(raw type)的类型检查不触发类型提升:if (a is B)中的B是未指定泛型参数的原始类型,编译器无法确认该B的泛型参数是否与A<int>的int匹配,出于类型安全考虑,不会将a的类型提升为B的具体泛型版本,因此分支内a仍保留A<int>类型,自然找不到B类特有的getter方法。
  • 明确泛型参数的类型检查会触发类型提升:if (a is B<int>)明确指定了泛型参数为int,编译器可以确认a的实际类型确实是B<int>,因此会自动将分支内a的类型提升为B<int>,此时就能直接访问B类的成员。

内容的提问来源于stack exchange,提问作者Valentin Vignal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:55:36