Dart中类型信息是否与is、as运算符绑定?代码示例答疑
Dart中is与as运算符的类型提升机制解析
第一段代码
void main() { Object i = new A(); bool b = (i is A); print(i.i); // this line gives error if (b) { print(i.i); // this executes with success } }
第二段代码
void main() { Object i = new A(); print(i.i); // this line gives error print((i as A).i); print(i.i); // this executes with success }
你观察到的现象,核心是**Dart的静态类型提升(Type Promotion)**机制在起作用,而非给对象附加额外类型信息,以下分别解释is和as的具体行为:
1. is运算符的类型提升
i is A是类型测试,运行时会检查i的实际类型是否为A(或其子类),返回布尔值。- 当你把测试结果赋值给
b并进入if (b)分支时,Dart静态分析器会推断:该分支仅在i is A为真时执行,因此会将i的静态类型从Object临时提升为A。此时编译器允许直接访问A类的i属性,因为静态类型已变为更具体的A。 - 分支外的
print(i.i)报错,是因为i的静态类型仍为Object,而Object类并没有i属性。
2. as运算符的类型提升
i as A是类型转换,运行时会先检查i是否为A的实例:- 如果是,直接返回原对象(既不创建新对象,也不修改原对象的类型);
- 如果不是,会抛出
CastError异常。
- 执行
(i as A).i后,Dart静态分析器会记录这次成功的转换操作,后续对i的访问会将其静态类型提升为A,因此后面的print(i.i)可以正常执行。
关键澄清
Dart不会在执行类型测试或转换时给对象附加任何额外类型信息。对象的运行时类型从创建时就确定(这里i的运行时类型始终是A),所有能访问属性的情况,都是静态分析器通过代码上下文推断出变量的实际类型,临时提升其静态类型,从而放宽了静态类型检查的限制。
内容的提问来源于stack exchange,提问作者Shiran Abbasi
相关产品推荐
相关产品推荐

