【发布时间】:2011-12-04 16:22:23
【问题描述】:
Dart 规范声明:
具体的类型信息反映了运行时对象的类型,并且总是可以通过动态类型检查构造( instanceOf、casts、typecase 等在其他语言中的类似物)。
听起来不错,但没有类似instanceof 的运算符。那么我们如何在 Dart 中执行运行时类型检查呢?有可能吗?
【问题讨论】:
标签: dynamic dart instanceof dart-mirrors
Dart 规范声明:
具体的类型信息反映了运行时对象的类型,并且总是可以通过动态类型检查构造( instanceOf、casts、typecase 等在其他语言中的类似物)。
听起来不错,但没有类似instanceof 的运算符。那么我们如何在 Dart 中执行运行时类型检查呢?有可能吗?
【问题讨论】:
标签: dynamic dart instanceof dart-mirrors
在 Dart 中 instanceof-operator 被称为 is。该规范对普通读者并不完全友好,因此目前最好的描述似乎是http://www.dartlang.org/articles/optional-types/。
这是一个例子:
class Foo { }
main() {
var foo = new Foo();
if (foo is Foo) {
print("it's a foo!");
}
}
【讨论】:
is 运算符。最好参考 Dart 源码中的语法文件:code.google.com/p/dart/source/browse/trunk/dart/language/…
is 运算符在规范的第 59 页第 10.30 节“类型测试”中定义
is 和 is! 可以在 Dart 语言导览的 Operators 部分找到。
getTypeName(dynamic obj) => obj.runtimeType;
!= 但is!...让我感到困惑不是它确实
Dart Object 类型有一个runtimeType 实例成员(来源来自dart-sdk v1.14,不知道之前是否可用)
class Object {
//...
external Type get runtimeType;
}
用法:
Object o = 'foo';
assert(o.runtimeType == String);
【讨论】:
runtimeType 可能会被类覆盖,尽管我想不出他们会这样做的原因。 (外部代码无法设置值,因为它是一个吸气剂)就个人而言,我会坚持is 和反射。
runtimeType 有这些限制并不是很明显。
正如其他人所提到的,Dart 的 is 运算符等同于 Javascript 的 instanceof 运算符。但是,我还没有在 Dart 中找到 typeof 运算符的直接类似物。
谢天谢地,dart:mirrors reflection API 最近已添加到 SDK,现在可以在 latest Editor+SDK package 中下载。这是一个简短的演示:
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
有两个用于类型测试的运算符:E is T 测试 E 类型 T 的实例,而 E is! T 测试 E 不是类型 T 的实例。
请注意,E is Object 始终为真,null is T 始终为假,除非T===Object。
【讨论】:
T===Object 的含义吗? Dart 没有三等号运算符,但您选择使用它而不是双等号,所以我认为差异很重要。
null is Object 是真的,但 null is T 对于任何其他类型的 T 都是假的。虽然我已经很多年没有靠近 Dart 所以不能确定。
精确的类型匹配是通过runtimeType 属性完成的。检查实例或其任何父类型(在继承链中)是否属于给定类型是通过is 运算符完成的:
class xxx {}
class yyy extends xxx {}
void main() {
var y = yyy();
print(y is xxx);
print(y.runtimeType == xxx);
}
返回:
true
false
【讨论】:
只是为了澄清is 和runtimeType 之间的区别。正如有人已经说过的(并且这是使用 Dart V2+ 测试的)以下代码:
class Foo {
@override
Type get runtimeType => String;
}
main() {
var foo = Foo();
if (foo is Foo) {
print("it's a foo!");
}
print("type is ${foo.runtimeType}");
}
将输出:
it's a foo!
type is String
这是错误的。 现在,我看不出为什么要这样做……
【讨论】:
只需调用
print(unknownDataType.runtimeType)
关于数据。
【讨论】:
print("请输入您的电话号码:\n"); var 电话号码 = stdin.readLineSync();
if(phone number.runtimeType is int == true) // checks if the values input are integers
{
print('you have successfully input your phone number!');
}
else{
print('only numbers are allowed');
}
【讨论】:
== true,表达式本身会解析为布尔值。您只需要if (thing is int) - 然后您会看到您的解决方案实际上与接受的答案相同。