这里有一些我觉得很有趣的 dart 代码:
void main() {
var someA = B();
A value = switch (someA) {
B() => B(),
C() => C(),
};
}
sealed class A<T extends num> {}
final class B extends A<int> {}
final class C extends A<double> {}
如果您尝试编译它,您会收到有关 switch 语句的错误:
A value of type 'Object' can't be assigned to a variable of type 'A<num>'. Try changing the type of the variable, or casting the right-hand type to 'A<num>'.
我的问题是,为什么编译器不推断两者之间的公共父类型? (好吧,我猜想……默认为
Object
。)如果你写了类似 var myThing = true ? 1.5 : 7;
的内容,dart 会将 myThing
的预期类型推断为 num
。为什么这里不这样做?
当然,一旦你这样做了,这一切就都解决了
void main() {
var someA = B();
A value = switch (someA) {
B() => B() as A,
C() => C() as A,
};
}
sealed class A<T extends num> {}
final class B extends A<int> {}
final class C extends A<double> {}
相反。另外,值得注意的是,当类型参数
<T extends num>
不存在时,这个问题就不会出现——所以泛型类型的一些东西会阻止编译器推断预期的类型(或者至少是我预期的类型)。
另一方面,这个稍作修改的版本可以按预期工作,无需进行转换(Dart 版本 3.3.0):
import 'dart:math';
sealed class A<T extends num> {}
final class B extends A<int> {}
final class C extends A<double> {}
void main() {
var rand = Random();
var someA = B();
var value = switch (someA) {
B() => B(),
C() => C(), // Dead code (message from the static analyzer).
};
print(value);
print(value.runtimeType);
var myThing = rand.nextDouble() > 0.5 ? 1.2: 1;
print(myThing.runtimeType);
}
另请注意,
myThing
可以推断为 int
或 double
。
$ dart main
Instance of 'B'
B
int