为什么我需要在详尽的 switch 表达式中显式向下转型?

问题描述 投票:0回答:1

这里有一些我觉得很有趣的 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 types type-inference
1个回答
0
投票

另一方面,这个稍作修改的版本可以按预期工作,无需进行转换(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
© www.soinside.com 2019 - 2024. All rights reserved.