Types Dart运行时类型签入开关语句

Types Dart运行时类型签入开关语句,types,switch-statement,dart,Types,Switch Statement,Dart,我发现一些奇怪的行为试图检查Dart中某些对象的运行时类型。 让我们举一个简单的例子: main(List<String> args) { List<Map> l1 = new List<Map>(); l1.add(new Map<String, int>()); List<int> l2 = ['Start', 'Stop']; checkType(l1.runtimeType); checkType(l1[0]

我发现一些奇怪的行为试图检查Dart中某些对象的运行时类型。 让我们举一个简单的例子:

main(List<String> args) {
  List<Map> l1 = new List<Map>();
  l1.add(new Map<String, int>());
  List<int> l2 = ['Start', 'Stop'];
  checkType(l1.runtimeType);
  checkType(l1[0].runtimeType);
  checkType(l2.runtimeType);
}

checkType(Type type) {

  switch(type) {
    case List:
      print('it is a List!');
      break;
    case Map:
      print('it is a List!');
      break;
    default:
      print('Unmanaged type $type');
      break;
  }
}
main(列表参数){
列表l1=新列表();
l1.添加(新映射());
列表l2=[‘开始’、‘停止’];
checkType(l1.runtimeType);
检查类型(l1[0]。运行时类型);
checkType(l2.runtimeType);
}
检查类型(类型){
开关(类型){
个案列表:
打印(“它是一个列表!”);
打破
案例图:
打印(“它是一个列表!”);
打破
违约:
打印(“非托管类型$type”);
打破
}
}
此程序具有以下输出:

非托管类型
列表
非托管类型
\u InternalLinkedHashMap
非托管类型
列表

无法在switch语句中检查第一种情况,因为如果尝试设置“
列表”
”情况,则会出现错误:在常量表达式中,此运算符的操作数必须为“num”类型 无法匹配第二个,因为在案例中使用_InternalLinkedHashMap会导致以下错误:案例表达式必须为常量

在最后一个例子中,我将列表定义为int的列表(
List
),但系统忽略它并将其视为简单列表。 我认为这是误导性的,这样的声明应该被禁止


有什么帮助/建议吗?

如果您想根据对象的类型进行流控制,那么实际上您想根据对象的类是否实现接口而不是运行时类型来进行流控制。这就是类型测试操作符
是什么
是什么适用于

请记住,在Dart中,类也是一个接口,所以您可以测试对象是否是特定的类

class Something {
 ...
}

var s = new Something();
print(s is Something);     // true
请注意,我们通常认为是“类”的东西,例如
List
an
Map
,不是类,而是接口。任何返回此类实例(包括构造函数)的操作实际上都会返回一个实现接口的类

您可以使用泛型,但要小心

void main() {

  var a = [1, 2, 'three'];
  print(a is List);          // True
  print(a is List<int>);     // True!!!!
  print(a is List<String>);  // True!!!!

  var b = new List<int>.from([1, 2, 3]);
  print(b is List);          // True
  print(b is List<int>);     // True
  print(b is List<String>);  // False
}

我想在这方面,你会从强模式中得到很多帮助。它会给你更多的警告/错误。使用
is
进行类型检查,例如
if(type是List){…}else if(type是Map){…}else{…}
switch
语句在此不起作用,并且不会检查通用参数
class Base {
  void a() {}
}

class Mix {
  void b() {}
}

class Mixed extends Base with Mix {} 

class Explicit implements Base {
  void a() {}  
}

void main() {

  var c = new Mixed();
  print(c is Mixed);         // True
  print(c is Base);          // True
  print(c is Mix);           // True

  var d = new Explicit();
  print(d is Base);          // True
}