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


103

Dart规范指出:

修饰的类型信息反映了运行时对象的类型,并且始终可以通过动态类型检查构造(其他语言中的instanceOf,casts,typecase等类似物)查询。

听起来不错,但没有instanceof类似运算符。那么我们如何在Dart中执行运行时类型检查?有可能吗?

Answers:


146

isDart中称为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!");
  }
}

看起来is规范中根本没有提到运算符。这是更好地参考,在飞镖源语法文件:code.google.com/p/dart/source/browse/trunk/dart/language/...
Idolon

4
@Idolon,该is操作被定义规范的第59页,部分10.30“型式试验”
邓肯

4
is并且is!可以在发现运营商达特语言游的部分。
卷曲

1
新语法是getTypeName(dynamic obj) => obj.runtimeType;
Mahdi Imani

1
!=但是is!...让我感到困惑,不是
吗?-atreeon

38

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

class Object {
  //...
  external Type get runtimeType;
}

用法:

Object o = 'foo';
assert(o.runtimeType == String);

11
RuntimeType仅用于调试目的,应用程序代码不应依赖于此。它可以通过类覆盖,以返回假值,并在transpiled到JS可能会返回不可用的值
君特Zöchbauer

1
感谢您的发言,我对Dart还是陌生的,我同意runtimeType可以被类覆盖,尽管我想不出为什么会这么做。(外部代码无法设置值,因为这是一个吸气剂)就个人而言,我会坚持is并反思。
sbedulin

2
没关系,这里提到。runtimeType有这些局限性不是很明显。
君特Zöchbauer

甘特,还是runtimeType应该只用于调试目的吗?我问是因为在Object或其他地方(我能找到)的文档中都没有提及这一点。
Matt C

1
@GünterZöchbauer注释在Dart 2中不再正确。现在使用它应该没问题。
vovahost

18

object.runtimeType 返回对象的类型

例如:

print("HELLO".runtimeType); //prints String
var x=0.0;
print(x.runtimeType); //prints double

7
sbedulin的答案已经解释了这一点。添加与现有答案相同的答案是没有意义的。另请参见他的答案下方的评论。
君特Zöchbauer

17

正如其他人提到的那样,Dart的is运算符等效于Javascript的instanceof运算符。但是,我没有typeof在Dart中找到该运算符的直接类似物。

值得庆幸的是,dart:mirrors反射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.");
}


这是一个很好的解决方案,但我们有错误: Unsupported operation: dart:mirrors is no longer supported for web apps
Mahdi Imani

@Lii这个答案是为Ecma TC52写的。参见dart.dev/faq
Rob

11

有两个用于类型测试的运算符:E is T测试E是类型T的实例,而E is! T测试E 不是类型T的实例。

请注意,除非E is Object始终为true,null is T否则始终为false T===Object


你能解释什么是什么意思T===Object吗?Dart没有三元等于运算符,但您选择使用它而不是双元等于,因此我认为这种区别很重要。
Matt C

@MattC那是七年前写的!我想我的意思是null is Object正确的,但null is T对于任何其他T. tbh都是错误的,尽管我已经很多年没去达特了,所以不能确定。
邓肯,

2

只是为了澄清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}");

}

将输出:

it's a foo! 
type is String

错了 现在,我不明白为什么要这样做。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.