Làm cách nào để thực hiện kiểm tra kiểu thời gian chạy trong Dart?


103

Thông số kỹ thuật của Dart cho biết:

Thông tin loại đã sửa đổi phản ánh các loại đối tượng trong thời gian chạy và có thể luôn được truy vấn bởi các cấu trúc đánh máy động (các tương tự của instanceOf, casts, typecase, v.v. trong các ngôn ngữ khác).

Nghe có vẻ tuyệt vời, nhưng không có instanceoftoán tử-like. Vậy làm cách nào để thực hiện kiểm tra kiểu thời gian chạy trong Dart? Có thể ở tất cả?

Câu trả lời:


147

Toán tử instanceof được gọi istrong Dart. Thông số kỹ thuật không chính xác thân thiện với người đọc thông thường, vì vậy mô tả tốt nhất hiện tại có vẻ là http://www.dartlang.org/articles/optional-types/ .

Đây là một ví dụ:

class Foo { }

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

Có vẻ như không có đề cập đến istoán tử nào trong đặc điểm kỹ thuật. Tốt hơn là nên tham khảo tệp ngữ pháp trong các nguồn Dart: code.google.com/p/dart/source/browse/trunk/dart/language/…
Idolon

4
@Idolon, các isnhà điều hành được xác định trên trang 59 của spec, phần 10.30 'Loại test'
Duncan

4
isis!có thể được tìm thấy trong phần Nhà điều hành của chuyến tham quan ngôn ngữ Dart.
Curly

1
cú pháp mới làgetTypeName(dynamic obj) => obj.runtimeType;
Mahdi Imani

1
!=nhưng is!... làm tôi bối rối không phải nó
atreeon 25/10 '19

38

ObjectLoại Dart có một runtimeTypethành viên thể hiện (nguồn là từ dart-sdkv1.14, không biết có trước đó không)

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

Sử dụng:

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

11
RuntimeType chỉ dành cho mục đích gỡ lỗi và mã ứng dụng không nên phụ thuộc vào nó. Nó có thể ghi đè bởi các lớp học để các giá trị giả trở lại và có lẽ trả về giá trị sử dụng được khi transpiled để JS
Günter Zöchbauer

1
Cảm ơn nhận xét của bạn, tôi còn khá mới với Dart, và tôi đồng ý rằng điều đó runtimeTypecó thể bị các lớp học ghi đè, mặc dù tôi không thể nghĩ ra lý do tại sao họ lại làm như vậy. (mã bên ngoài không thể đặt giá trị vì nó là một getter) Cá nhân tôi sẽ bám vào isvà phản ánh.
sbedulin

2
Nó tốt, điều này được đề cập ở đây. Nó không phải là rất rõ ràng rằng runtimeTypecó những hạn chế.
Günter Zöchbauer

Gunter, nó vẫn còn trường hợp runtimeTypechỉ nên được sử dụng cho mục đích gỡ lỗi? Tôi hỏi vì không có bất kỳ đề cập nào về điều này trong tài liệu dành cho Đối tượng hoặc ở nơi khác (mà tôi có thể tìm thấy).
Matt C

1
@ GünterZöchbauer bình luận không còn đúng trong Dart 2. Bây giờ sử dụng nó sẽ ổn.
vovahost

18

object.runtimeType trả về loại đối tượng

Ví dụ:

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

7
Câu trả lời từ sbedulin đã giải thích điều đó. Không có ích gì khi thêm câu trả lời giống như những câu hiện có. Xem thêm bình luận bên dưới câu trả lời của anh ấy.
Günter Zöchbauer

17

Như những người khác đã đề cập, istoán tử của Dart tương đương với instanceoftoán tử của Javascript . Tuy nhiên, tôi đã không tìm thấy một chất tương tự trực tiếp củatypeof nhà điều hành trong Dart.

Rất may, API phản chiếu dart: mirror gần đây đã được thêm vào SDK và hiện có sẵn để tải xuống trong gói Editor + SDK mới nhất . Đây là một bản demo ngắn:

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


đó là giải pháp tốt, nhưng chúng tôi có lỗi: Unsupported operation: dart:mirrors is no longer supported for web apps
Mahdi Imani

@Lii Câu trả lời này được viết cho Ecma TC52. Xem dart.dev/faq
Rob

11

Có hai toán tử để kiểm tra kiểu: E is Tkiểm tra E một thể hiện của kiểu T trong khi E is! Tkiểm tra E thì không là thể của kiểu T.

Lưu ý rằng E is Objectluôn đúng và null is Tluôn sai trừ khi T===Object.


Bạn có thể giải thích những gì có nghĩa là bởi T===Object? Dart không có toán tử ba bằng, nhưng bạn đã chọn sử dụng nó thay vì hai bằng, vì vậy tôi cho rằng sự khác biệt có ý nghĩa.
Matt C

@MattC Điều đó đã được viết cách đây hơn 7 năm! Tôi nghĩ những gì tôi muốn nói là null is Objectđúng nhưng null is Tsai đối với bất kỳ loại nào khác T. tbh mặc dù tôi đã không ở gần Dart nhiều năm nay nên không thể chắc chắn.
Duncan

2

Chỉ để làm rõ một chút sự khác biệt giữa isruntimeType. Như ai đó đã nói (và điều này đã được thử nghiệm với Dart V2 +) đoạn mã sau:

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

}

sẽ xuất:

it's a foo! 
type is String

Sai chỗ nào. Bây giờ, tôi không thể hiểu lý do tại sao một người nên làm một điều như vậy ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.