ChatGPT解决这个技术问题 Extra ChatGPT

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

Dart 规范指出:

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

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


G
Günter Zöchbauer

在 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/…
@Idolon,is 运算符在规范的第 59 页第 10.30 节“类型测试”中定义
isis! 可以在 Dart 语言导览的 Operators 部分中找到。
新语法是 getTypeName(dynamic obj) => obj.runtimeType;
!=is!...让我困惑不是它确实
s
sbedulin

Dart Object 类型有一个 runtimeType 实例成员(来源来自 dart-sdk v1.14,不知道之前是否可用)

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

用法:

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

RuntimeType 仅用于调试目的,应用程序代码不应依赖它。它可以被类覆盖以返回假值,并且在转译为 JS 时可能返回不可用的值
感谢您的评论,我对 Dart 很陌生,我同意 runtimeType 可能会被类覆盖,尽管我想不出他们会这样做的原因。 (外部代码无法设置值,因为它是一个吸气剂)就个人而言,我会坚持 is 和反射。
没关系,这里提到了这个。 runtimeType 有这些限制并不是很明显。
@GünterZöchbauer 评论在 Dart 2 中不再适用。现在使用它应该没问题。
我不确定他为什么认为 Dart 2 没问题。也许我错过了一些东西。
R
Rob

正如其他人所提到的,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
@Lii 这个答案是为 Ecma TC52 写的。请参阅dart.dev/faq
请注意,如果您使用 Flutter,它会禁用反射(因为它会破坏树抖动)。
D
Duncan

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

请注意,E is Object 始终为真,而 null is T 始终为假,除非 T===Object


你能解释一下T===Object是什么意思吗? Dart 没有三等号运算符,但您选择使用它而不是双等号,所以我认为差异很重要。
@MattC 那是 7 年前写的!我想我的意思是 null is Object 是真的,但对于任何其他类型的 T 来说 null is T 是假的。虽然我已经很多年没有靠近 Dart 所以不能确定。
你救了我的一天!有了这个:var isAuthFailure = Failure is! AuthenticationFailure;
M
Maxim Saplin

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

class xxx {}

class yyy extends xxx {}

void main() {
  var y = yyy();
  
  print(y is xxx);
  print(y.runtimeType == xxx);
}

回报:

true
false

2
2 revs, 2 users 89%

只是为了澄清一下 isruntimeType 之间的区别。正如有人已经说过的(并且这是使用 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

这是错误的。现在,我看不出一个人应该做这种事情的原因......


A
Alish Giri

只需在属性上使用 .runtimeType,如下所示,

print(unknownDataTypeProperty.runtimeType)

l
lava

T 是类型

   print( T.runtimeType)

https://i.stack.imgur.com/aFx70.png

https://i.stack.imgur.com/rQRGh.png


K
Kolawole Elijah

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) - 然后您会看到您的解决方案实际上与接受的答案相同。
电话号码实际上不是数字。它们可能以 + 符号开头,它们可能包含重要的前导零,它们可能包含空格......并且您的代码无法编译,因为您设法在变量名中隐藏了一个空格。