Bagaimana cara melakukan pemeriksaan tipe runtime di Dart?

110

Spesifikasi Dart menyatakan:

Informasi tipe Reified mencerminkan tipe objek pada saat runtime dan mungkin selalu ditanyai oleh konstruksi pemeriksaan tipe dinamis (analog dari instanceOf, cast, typecase, dll. Dalam bahasa lain).

Kedengarannya bagus, tapi tidak ada instanceofoperator yang mirip. Jadi bagaimana kita melakukan pemeriksaan jenis runtime di Dart? Apakah mungkin sama sekali?

Idolon
sumber

Jawaban:

159

Instanceof-operator disebut isDart. Spesifikasi ini tidak sepenuhnya ramah untuk pembaca biasa, jadi deskripsi terbaik saat ini sepertinya adalah http://www.dartlang.org/articles/optional-types/ .

Berikut contohnya:

class Foo { }

main() {
  var foo = new Foo();
  if (foo is Foo) {
    print("it's a foo!");
  }
}
Patrick
sumber
Sepertinya tidak ada isoperator sama sekali dalam spesifikasinya. Lebih baik merujuk ke file tata bahasa di sumber Dart: code.google.com/p/dart/source/browse/trunk/dart/language/…
Idolon
4
@Idolon, isoperator ditentukan pada halaman 59 dari spesifikasi, bagian 10.30 'Tes jenis'
Duncan
5
isdan is!dapat ditemukan di bagian Operator tur bahasa Dart.
Curly
1
sintaks baru adalahgetTypeName(dynamic obj) => obj.runtimeType;
Mahdi Imani
1
!=tapi is!... membingungkan saya bukan
tanggal
40

ObjectJenis Dart memiliki anggota runtimeTypeinstance (sumber dari dart-sdkv1.14, tidak tahu apakah itu tersedia sebelumnya)

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

Pemakaian:

Object o = 'foo';
assert(o.runtimeType == String);
sbedulin.dll
sumber
11
RuntimeType hanya untuk tujuan debugging dan kode aplikasi tidak boleh bergantung padanya. Ini dapat ditimpa oleh kelas untuk mengembalikan nilai palsu dan mungkin mengembalikan nilai yang tidak dapat digunakan ketika ditransformasikan ke JS
Günter Zöchbauer
1
Terima kasih atas komentar Anda, saya cukup baru mengenal Dart, dan saya setuju itu runtimeTypemungkin dikesampingkan oleh kelas, meskipun saya tidak dapat memikirkan alasan mengapa mereka melakukannya. (kode eksternal tidak dapat mengatur nilai karena itu pengambil) Secara pribadi, saya akan tetap berpegang pada isdan refleksi.
sbedulin
2
Tidak apa-apa ini disebutkan di sini. Tidak terlalu jelas bahwa mereka runtimeTypememiliki batasan ini.
Günter Zöchbauer
Gunter, apakah masih kasus yang runtimeTypeseharusnya hanya digunakan untuk tujuan debugging? Saya bertanya karena tidak ada penyebutan ini di dokumen untuk Object, atau di tempat lain (yang bisa saya temukan).
Matt C
1
Komentar @ GünterZöchbauer tidak berlaku lagi di Dart 2. Seharusnya tidak masalah untuk menggunakannya sekarang.
vovahost
21

object.runtimeType mengembalikan tipe objek

Sebagai contoh:

print("HELLO".runtimeType); //prints String
var x=0.0;
print(x.runtimeType); //prints double
Raj Yadav
sumber
7
Jawaban dari sbedulin sudah menjelaskan hal itu. Tidak ada gunanya menambahkan jawaban yang sama dengan jawaban yang sudah ada. Simak juga komentar di bawah jawabannya.
Günter Zöchbauer
17

Seperti yang telah disebutkan orang lain, isoperator Dart setara dengan instanceofoperator Javascript . Namun, saya belum menemukan analog langsung dari typeofoperator di Dart.

Untungnya, API refleksi dart: mirrors baru-baru ini telah ditambahkan ke SDK, dan sekarang tersedia untuk diunduh dalam paket Editor + SDK terbaru . Berikut demo singkatnya:

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.");
}
rampok
sumber
ini adalah solusi yang baik tetapi, kami memiliki kesalahan: Unsupported operation: dart:mirrors is no longer supported for web apps
Mahdi Imani
@Lii Jawaban ini ditulis untuk Ecma TC52. Lihat dart.dev/faq
Rob
12

Ada dua operator untuk pengujian tipe: E is Tpengujian untuk E sebuah turunan dari tipe T sementara E is! Ttes untuk E bukan sebuah turunan dari tipe T.

Perhatikan bahwa E is Objectselalu benar, dan null is Tselalu salah kecuali T===Object.

Duncan
sumber
Bisakah Anda menjelaskan apa yang dimaksud dengan T===Object? Dart tidak memiliki operator rangkap tiga sama dengan, tetapi Anda memilih untuk menggunakannya daripada menggandakan sama, jadi saya berasumsi perbedaannya memiliki signifikansi.
Matt C
@MattC Itu ditulis lebih dari 7 tahun yang lalu! Saya pikir yang saya maksud adalah null is Objectbenar tetapi null is Tsalah untuk tipe T. tbh lainnya meskipun saya belum pernah dekat Dart selama bertahun-tahun sekarang jadi tidak bisa memastikan.
Duncan
5

Hanya untuk memperjelas sedikit perbedaan antara isdan runtimeType. Seperti yang dikatakan seseorang (dan ini telah diuji dengan Dart V2 +) kode berikut:

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

}

akan mengeluarkan:

it's a foo! 
type is String

Yang mana yang salah. Sekarang, saya tidak dapat melihat alasan mengapa seseorang harus melakukan hal seperti itu ...

Edoardo
sumber
0

Telepon saja

print (unknownDataType.runtimeType)

pada data.

Alish Giri
sumber