Dart'ta çalışma zamanı tür denetimi nasıl yapılır?


110

Dart özelliği durumları:

Gerçekleştirilmiş tip bilgisi, çalışma zamanında nesnelerin tiplerini yansıtır ve her zaman dinamik tip kontrol yapıları tarafından sorgulanabilir (diğer dillerdeki instanceOf, cast, typecase vb. Analogları).

Kulağa harika geliyor, ancak instanceofbenzeri olmayan operatör yok . Peki, Dart'ta çalışma zamanı tip kontrolünü nasıl gerçekleştiririz? Bütün bunlar mümkün mü?

Yanıtlar:


160

İnstanceof-operatörü isDart'ta çağrılır . Spesifikasyon, sıradan bir okuyucu için tam olarak dostça değildir, bu yüzden şu anda en iyi açıklama http://www.dartlang.org/articles/optional-types/ gibi görünüyor .

İşte bir örnek:

class Foo { }

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

isSpesifikasyonda operatörden hiç bahsedilmiyor gibi görünüyor . Dart kaynaklarındaki dilbilgisi dosyasında hakemlik yapmak daha iyidir: code.google.com/p/dart/source/browse/trunk/dart/language/…
Idolon

4
@Idolon, isoperatör şartnamenin 59. sayfasında, 10.30 'Tip testi' bölümünde
Duncan

5
isve Dart dili turunun Operatörler bölümünde is!bulunabilir .
Curly

1
yeni sözdizimigetTypeName(dynamic obj) => obj.runtimeType;
Mehdi Imani

1
!=ama is!...
kafamı

41

Dart Objecttürünün bir runtimeTypeörnek üyesi var (kaynak dart-sdkv1.14'ten geliyor, daha önce mevcut olup olmadığını bilmiyorum)

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

Kullanım:

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

11
RuntimeType yalnızca hata ayıklama amaçlıdır ve uygulama kodu buna bağlı olmamalıdır. Sahte değerler döndürmek için sınıflar tarafından geçersiz kılınabilir ve muhtemelen JS'ye aktarıldığında kullanılamaz değerler döndürür
Günter Zöchbauer

1
Yorumunuz için teşekkürler, Dart'ta oldukça yeniyim ve bunun runtimeTypesınıflar tarafından geçersiz kılınabileceği konusunda hemfikirim , ancak neden böyle olduklarını düşünemiyorum. (harici kod sinse değerini ayarlayamaz, bu bir alıcıdır) Şahsen ben sadık kalırdım isve düşünürdüm .
sbedulin

2
Sorun değil, burada bahsediliyor. Bu runtimeTypesınırlamalara sahip olduğu çok açık değil .
Günter Zöchbauer

Gunter, runtimeTypeyalnızca hata ayıklama amacıyla kullanılması gereken durum hala bu mu? Soruyorum çünkü Object belgelerinde veya başka bir yerde (bulabildiğim) bundan bahsedilmiyor.
Matt C

1
@ GünterZöchbauer yorumu artık Dart 2'de doğru değil. Şimdi kullanmakta sorun yok.
vovahost

22

object.runtimeType nesnenin türünü döndürür

Örneğin:

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

7
Sbedulin'in cevabı bunu zaten açıklıyor. Mevcut cevaplarla aynı cevabı eklemenin bir anlamı yok. Cevabının altındaki yorumlara da bakınız.
Günter Zöchbauer

17

Diğerlerinin de belirttiği gibi, Dart'ın isoperatörü Javascript instanceofoperatörünün eşdeğeridir . Ancak, typeofDart'ta operatörün doğrudan bir analogunu bulamadım .

Neyse ki, dart: mirror yansıma API'si yakın zamanda SDK'ya eklendi ve artık en son Editor + SDK paketiyle indirilebilir . İşte kısa bir demo:

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.");
}


iyi bir çözüm ama Unsupported operation: dart:mirrors is no longer supported for web apps
hatamız

@Lii Bu yanıt Ecma TC52 için yazılmıştır. Bkz. Dart.dev/faq
Rob

12

Tip testi için iki operatör vardır: E is TE için E is! Ttestler T tipi bir örnek, E için testler T tipi bir örnek değil .

Bunun E is Objecther zaman doğru olduğunu ve null is Tolmadıkça her zaman yanlış olduğunu unutmayın T===Object.


İle neyin kastedildiğini açıklayabilir misiniz T===Object? Dart'ın üçlü eşittir operatörü yoktur, ancak siz onu çift eşittir yerine kullanmayı seçtiniz, bu nedenle farkın anlamlı olduğunu varsayıyorum.
Matt C

@MattC Bu 7 yıldan daha önce yazılmıştı! Sanırım ne demek null is Objectistediğim doğru olabilirdi ama null is Tdiğer tipler için yanlıştı.
Duncan

5

Sadece biraz arasındaki farkı netleştirmek isve runtimeType. Birinin daha önce söylediği gibi (ve bu Dart V2 + ile test edildi) aşağıdaki kod:

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}");

}

çıktı:

it's a foo! 
type is String

Hangisi yanlış. Şimdi, böyle bir şeyin neden yapılması gerektiğini anlayamıyorum ...


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.