如何在Dart中执行运行时类型检查?

Ido*_*lon 64 dynamic instanceof dart dart-mirrors

飞镖规格说明:

已知类型信息反映了运行时对象的类型,并且可能始终通过动态类型检查构造(其他语言中的instanceOf,casts,typecase等的类比)来查询.

听起来不错,但是没有instanceof类似的操作员.那么我们如何在Dart中执行运行时类型检查?有可能吗?

小智 90

is在Dart中调用instanceof-operator .规范对于一个随意的读者来说并不是很友好,所以现在最好的描述似乎是http://www.dartlang.org/articles/optional-types/.

这是一个例子:

class Foo { }

main() {
  var foo = new Foo();
  if (foo is Foo) {
    print("it's a foo!");
  }
}
Run Code Online (Sandbox Code Playgroud)

  • `is` 和 `is!` 可以在 Dart 语言导览的 [Operators](https://dart.dev/guides/language/language-tour#type-test-operators) 部分找到。 (10认同)
  • @Idolon,`is`运算符在规范的第59页定义,第10.30节'类型测试' (4认同)
  • 新语法是 `getTypeName(dynamic obj) => obj.runtimeType;` (3认同)
  • `!=` 但 `is!`...让我困惑,但事实并非如此 (3认同)
  • 看起来规范中根本没有提到“is”运算符。最好参考Dart源中的语法文件:https://code.google.com/p/dart/source/browse/trunk/dart/language/grammar/Dart.g (2认同)
  • 确保你没有在这里组合两种不同的方法并最终得到“foo.runtimeType is String”,这让我搞砸了一段时间。 (2认同)

sbe*_*lin 21

Dart Object类型具有runtimeType实例成员(来源来自dart-sdkv1.14,不知道它是否较早可用)

class Object {
  //...
  external Type get runtimeType;
}
Run Code Online (Sandbox Code Playgroud)

用法:

Object o = 'foo';
assert(o.runtimeType == String);
Run Code Online (Sandbox Code Playgroud)

  • RuntimeType仅用于调试目的,应用程序代码不应依赖于此。它可以被类覆盖以返回假值,并且在转换为JS时可能返回不可用的值 (6认同)
  • @GünterZöchbauer 评论在 Dart 2 中不再正确。现在使用它应该没问题。 (3认同)
  • 没关系,这里提到。不太明显的是`runtimeType`具有这些限制。 (2认同)

Rob*_*Rob 16

正如其他人所提到的,Dart的is运算符相当于Javascript的instanceof运算符.但是,我还没有找到typeofDart中操作员的直接模拟.

值得庆幸的是,dart:mirror reflection API最近已添加到SDK中,现在可以在最新的Editor + SDK包中下载.这是一个简短的演示:

import 'dart:mirrors'; 

getTypeName(dynamic obj) {
  return reflect(obj).type.reflectedType.toString();
}

void main() {
  var val = "\"Dart is dynamically typed (with optional type annotations.)\"";
  if (val is String) {
    print("The value is a String, but I needed "
        "to check with an explicit condition.");
  }
  var typeName = getTypeName(val);
  print("\nThe mirrored type of the value is $typeName.");
}
Run Code Online (Sandbox Code Playgroud)


Dun*_*can 10

有两个类型测试运算符:E is TE测试类型为T的实例,而E is! TE测试不是类型T的实例.

请注意,E is Object它始终为true,并且null is T始终为false,除非T===Object.


Raj*_*dav 9

object.runtimeType 返回对象的类型

例如:

print("HELLO".runtimeType); //prints String
var x=0.0;
print(x.runtimeType); //prints double
Run Code Online (Sandbox Code Playgroud)

  • sbedulin 的回答已经说明了这一点。添加与现有答案相同的答案是没有意义的。另请参阅他的回答下方的评论。 (13认同)

Edo*_*rdo 7

只是为了澄清is和之间的区别runtimeType。正如有人已经说过的(这是用 Dart V2+ 测试过的)以下代码:

class Foo { 
  Type get runtimeType => String;
}
main() {
  var foo = new Foo();
  if (foo is Foo) {
    print("it's a foo!");
  }
  print("type is ${foo.runtimeType}");

}
Run Code Online (Sandbox Code Playgroud)

将输出:

it's a foo! 
type is String
Run Code Online (Sandbox Code Playgroud)

这是错误的。现在,我看不出为什么要这样做……


Max*_*lin 7

精确的类型匹配是通过runtimeType属性完成的,检查实例或任何父级(在继承链中)是否属于给定类型是用is运算符完成的:

class xxx {}

class yyy extends xxx {}

void main() {
  var y = yyy();
  
  print(y is xxx);
  print(y.runtimeType == xxx);
}
Run Code Online (Sandbox Code Playgroud)

返回:

true
false
Run Code Online (Sandbox Code Playgroud)


Ali*_*iri 6

只需致电

打印(unknownDataType.runtimeType)

在数据上。