Dart에서 런타임 유형 검사를 수행하는 방법은 무엇입니까?


109

Dart 사양은 다음과 같이 설명합니다.

수정 된 유형 정보는 런타임시 객체 유형을 반영하며 항상 동적 유형 검사 구조 (다른 언어의 instanceOf, 캐스트, 유형 케이스 등의 유사체)에 의해 쿼리 될 수 있습니다.

훌륭하게 들리지만 instanceof유사 연산자 는 없습니다 . 그렇다면 Dart에서 런타임 유형 검사를 어떻게 수행할까요? 전혀 가능합니까?

답변:


157

instanceof-operator는 isDart에서 호출 됩니다. 사양은 평범한 독자에게 정확히 친숙하지 않으므로 현재 가장 좋은 설명은 http://www.dartlang.org/articles/optional-types/ 입니다.

예를 들면 다음과 같습니다.

class Foo { }

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

is사양 에 연산자에 대한 언급이 전혀없는 것 같습니다 . 그것은 다트 소스의 문법 파일을 참조하지만 것이 좋습니다 : code.google.com/p/dart/source/browse/trunk/dart/language/...
Idolon

4
@Idolon, is연산자는 사양의 59 페이지, 섹션 10.30 '유형 테스트'에 정의되어 있습니다.
Duncan

4
isis!에서 찾을 수 있습니다 연산자 다트 언어 투어의 섹션을 참조하십시오.
Curly

1
새로운 구문은getTypeName(dynamic obj) => obj.runtimeType;
마흐디 Imani

1
!=하지만 is!... 혼동하지 않습니다
atreeon

40

Dart Object유형에는 runtimeType인스턴스 멤버가 있습니다 (소스는 dart-sdkv1.14 에서 가져온 것입니다. 이전에 사용 가능했는지 알 수 없음)

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

용법:

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

11
RuntimeType은 디버깅 목적으로 만 사용되며 응용 프로그램 코드가 이에 의존해서는 안됩니다. 그것은 반환 가짜 값으로 클래스에 의해 오버라이드 (override)하고 JS에 transpiled 때 아마 사용할 수없는 값을 반환 할 수 있습니다
귄터 Zöchbauer

1
의견을 보내 주셔서 감사합니다. 저는 Dart를 처음 접 runtimeType했습니다. 클래스에 의해 무시 될 수 있다는 데 동의합니다 . 이유를 생각할 수는 없습니다. (외부 코드는 값을 설정할 수 없습니다. 그것은 게터입니다.) 개인적으로 저는 고수 is하고 반성합니다.
sbedulin 2016 년

2
여기에 언급 된 것이 좋습니다. runtimeType이러한 제한이있는 것은 분명하지 않습니다 .
Günter Zöchbauer

Gunter, 여전히 runtimeType디버깅 목적으로 만 사용해야 하는 경우 입니까? Object에 대한 문서 또는 다른 곳에서 이에 대한 언급이 없기 때문에 묻습니다.
Matt C

1
@ GünterZöchbauer 코멘트는 Dart 2에서 더 이상 사실이 아닙니다. 지금 사용해도 좋습니다.
vovahost

21

object.runtimeType 객체의 유형을 반환

예를 들면 :

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

7
스베 둘린의 대답은 이미 그것을 설명합니다. 기존 답변과 동일한 답변을 추가하는 것은 의미가 없습니다. 그의 답변 아래의 주석도 참조하십시오.
Günter Zöchbauer

17

다른 사람들이 언급했듯이 Dart의 is연산자는 Javascript의 instanceof연산자 와 동일 합니다. 그러나 typeofDart 에서 연산자와 직접적인 유사점을 찾지 못했습니다 .

고맙게도 dart : mirrors 리플렉션 API 가 최근 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
마흐디 Imani

@Lii이 답변은 Ecma TC52 용으로 작성되었습니다. dart.dev/faq
Rob

12

유형 테스트를위한 두 개의 연산자가 있습니다 : E is T테스트는 E, 형태 T의 인스턴스는 동안 E is! TE를위한 테스트 하지 T 형식의 인스턴스

참고 E is Object항상 true이고, null is T항상하지 않는 한 false입니다 T===Object.


의 의미를 설명해 주 T===Object시겠습니까? Dart에는 triple equals 연산자가 없지만 double equals 대신 사용하기로 선택했기 때문에 차이가 중요하다고 가정합니다.
Matt C

@MattC 7 년 이상 전에 작성되었습니다! 내가 의미하는 바는 다른 유형의 T. tbh에 대해서는 null is Object사실이지만 null is T거짓 일 것이라고 생각 합니다. 비록 지금까지 다트 근처에 수년 동안 가본 적이 없기 때문에 확신 할 수 없습니다.
Duncan

5

그냥 조금에게 차이 명확하게 isruntimeType. 누군가가 이미 말했듯이 (그리고 이것은 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

어느 것이 잘못되었습니다. 이제 왜 그런 일을해야하는지 모르겠네요 ...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.