Як виконати перевірку типу виконання в Dart?


103

У специфікації дротиків зазначено:

Інформація про тип, що підтверджена, відображає типи об'єктів під час виконання і завжди може запитуватися за допомогою динамічних конструкцій перевірки типу (аналоги instanceOf, casts, typecase тощо іншими мовами).

Звучить чудово, але немає instanceofподібного оператора. Отже, як нам виконати перевірку типу виконання в Dart? Чи можливо це взагалі?

Відповіді:


147

Екземпляр-оператора викликається isв Dart. Специфікація не зовсім привітна для випадкового читача, тому найкращим описом зараз є 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/…
Ідолон,

4
@Idolon, isоператор визначений на сторінці 59 специфікації, розділ 10.30 "Випробування типу"
Duncan,

4
isта is!їх можна знайти в розділі " Оператори " мовної екскурсії Dart.
Кучерявий

1
новий синтаксисgetTypeName(dynamic obj) => obj.runtimeType;
Mahdi

1
!=але is!... бентежить мене не так
атріон

38

У Objectтипі Dart є runtimeTypeчлен екземпляра (джерело з dart-sdkверсії 1.1, не знаю, чи було це раніше)

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

Використання:

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

11
RuntimeType призначений лише для налагодження, і код програми не повинен залежати від нього. Це може бути замінено класами для повернення фальшивих значень і, ймовірно, повертає непридатні значення при трансляції до JS
Günter Zöchbauer

1
Дякую за ваше зауваження, я досить новачок у Дарті, і я погоджуюсь, що це runtimeTypeможе бути замінено класами, хоча я не можу придумати причини, чому б вони це зробили. (зовнішній код не може встановити значення sinse it is getter) Особисто я б дотримувався isі роздумів.
sbedulin

2
Чудово, про це тут згадується. Не дуже очевидно, що runtimeTypeмають ці обмеження.
Günter Zöchbauer

Гюнтер, чи все-таки це справа, яку runtimeTypeслід використовувати лише для налагодження? Я запитую, бо про це немає жодної згадки в документації для Object або деінде (що я міг знайти).
Matt C

1
Коментар @ GünterZöchbauer більше не відповідає дійсності в Дарті 2. Це має бути чудово використовувати зараз.
vovahost

18

object.runtimeType повертає тип об'єкта

Наприклад:

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

7
Відповідь від «Сбедуліна» це вже пояснює. Немає сенсу додавати ту саму відповідь, що і існуючі. Дивіться також коментарі під його відповіддю.
Günter Zöchbauer

17

Як зазначали інші, isоператор Дарта є еквівалентом instanceofоператора Javascript . Однак я не знайшов прямого аналога typeofоператора в Дарті.

На щастя, нещодавно API SD для дзеркал був доданий до 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

@Lii Цю відповідь написано для Ecma TC52. Дивіться dart.dev/faq
Роб

11

Існує два оператори для перевірки типу: E is Tтести для E - екземпляр типу T, тоді як E is! Tтести для E - не екземпляр типу T.

Зверніть увагу, що E is Objectце завжди істина, і null is Tзавжди помилково, якщо T===Object.


Не могли б ви пояснити, що мається на увазі під T===Object? Дарт не має оператора потрійного дорівнює, але ви вирішили використовувати його, а не подвійне дорівнює, тому я припускаю, що різниця має значення.
Matt C

@MattC Це було написано більше 7 років тому! Думаю, те, що я мав на увазі, було 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

Що неправильно. Зараз я не можу зрозуміти причину, чому слід робити щось таке ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.