下面是一些我觉得很有趣的dart 代码:
void main() {
A<num> 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> {}
如果您try 编译此代码,则会得到有关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() {
A<num> 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>
不存在时,不会出现这个问题--所以泛型类型的某些方面阻止了编译器推断预期的类型(或者至少是我预期的类型).
编辑:switch
个表达式的行为和列表表达式之间有一个有趣的区别(如果你将它们结合在一起):
void main() {
// `values_var` is `List<Object>`
var values_var = [B(), C()];
List<A> values_List1 = [B(), C()];
List<A<num>> values_List2 = [B(), C()];
// all of the above compiles fine
A<num> someA = B();
// does not compile
A value = switch (someA) {
B() => B(),
C() => C(),
};
// DOES compile
List<A> value = switch (someA) {
B() => [B()],
C() => [C()],
};
}
这是我最初问题的一个更清晰的版本:为什么类型推断像我期望的那样对列表起作用,而对switch
个表达式(没有列表)却不起作用?