添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Reified type information reflects the types of objects at runtime and may always be queried by dynamic typechecking constructs (the analogs of instanceOf, casts, typecase etc. in other languages).

Sounds great, but there is no instanceof -like operator. So how do we perform runtime type-checking in Dart? Is it possible at all?

The instanceof-operator is called is in Dart. The spec isn't exactly friendly to a casual reader, so the best description right now seems to be http://www.dartlang.org/articles/optional-types/ .

Here's an example:

class Foo { }
main() {
  var foo = new Foo();
  if (foo is Foo) {
    print("it's a foo!");
                Looks like there is no mention of is operator at all in the specification. It's better to refere to the grammar file in Dart sources: code.google.com/p/dart/source/browse/trunk/dart/language/…
– Idolon
                Oct 10, 2011 at 17:11

Dart Object type has a runtimeType instance member (source is from dart-sdk v1.14, don't know if it was available earlier)

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

Usage:

Object o = 'foo';
assert(o.runtimeType == String);
                RuntimeType is only for debugging purposes and the application code shouldn't depend on it. It can be overridden by classes to return fake values and probably returns unusable values when transpiled to JS
– Günter Zöchbauer
                Mar 11, 2016 at 21:33
                Thanks for your remark, I'm pretty new to Dart, and I agree that runtimeType may be overriden by classes, although I can't think of a reason why they would. (external code can't set the value sinse it's a getter) Personally, I would stick to is and reflection.
– sbedulin
                Mar 11, 2016 at 22:47
                It's fine this is mentioned here. It's not very obvious that runtimeType has these limitations.
– Günter Zöchbauer
                Mar 12, 2016 at 8:43

As others have mentioned, Dart's is operator is the equivalent of Javascript's instanceof operator. However, I haven't found a direct analogue of the typeof operator in Dart.

Thankfully the dart:mirrors reflection API has recently been added to the SDK, and is now available for download in the latest Editor+SDK package. Here's a short 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.");
                it is good solution but, we have error:  Unsupported operation: dart:mirrors is no longer supported for web apps
– Mahdi Imani
                Sep 28, 2019 at 7:50
                Be aware that Flutter, if you're using that, disables reflection (because it breaks tree shaking).
– Ian
                Apr 14, 2021 at 18:26

There are two operators for type testing: E is T tests for E an instance of type T while E is! T tests for E not an instance of type T.

Note that E is Object is always true, and null is T is always false unless T===Object.

Could you explain what is meant by by T===Object? Dart doesn't have the triple equals operator, but you chose to use it rather than double equals, so I assume the difference has significance. – Matt C Apr 10, 2019 at 17:02 @MattC That was written more than 7 years ago! I think what I meant was null is Object would be true but null is T false for any other type T. tbh though I haven't been near Dart for many years now so can't be certain. – Duncan Apr 12, 2019 at 14:23

Exact type matching is done via runtimeType property. Checking if an instance or any of its parent types (in the inheritance chain) is of the given type is done via is operator:

class xxx {}
class yyy extends xxx {}
void main() {
  var y = yyy();
  print(y is xxx);
  print(y.runtimeType == xxx);

Returns:

false

Just to clarify a bit the difference between is and runtimeType. As someone said already (and this was tested with Dart V2+) the following code:

class Foo {
  @override
  Type get runtimeType => String;
main() {
  var foo = Foo();
  if (foo is Foo) {
    print("it's a foo!");
  print("type is ${foo.runtimeType}");

will output:

it's a foo! 
type is String

Which is wrong. Now, I can't see the reason why one should do such a thing...

to check whether the type of a variable is the same as your expected use is or runtimeType

void main() {
  int a = 10;
  print(a.runtimeType == int); // true
  print(a is int); // true
                Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
– Community
                Feb 1 at 15:51
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.