2016-07-13 2 views
1

私は、Dartのいくつかのオブジェクトの実行時の型をチェックしようとしているいくつかの奇妙な振る舞いを見つけました。 簡単な例を作ってみましょう:switch文のダートランタイムタイプのチェック

main(List<String> args) { 
    List<Map> l1 = new List<Map>(); 
    l1.add(new Map<String, int>()); 
    List<int> l2 = ['Start', 'Stop']; 
    checkType(l1.runtimeType); 
    checkType(l1[0].runtimeType); 
    checkType(l2.runtimeType); 
} 

checkType(Type type) { 

    switch(type) { 
    case List: 
     print('it is a List!'); 
     break; 
    case Map: 
     print('it is a List!'); 
     break; 
    default: 
     print('Unmanaged type $type'); 
     break; 
    } 
} 

このプログラムは、以下の出力があります。

アンマネージドタイプList<Map> アンマネージドタイプ_InternalLinkedHashMap<String, int> List

最初のケースは、switch文で確認することができないアンマネージドタイプ私が "List<Map>"の場合を設定しようとするとエラーが出るので、定数式では、この演算子のオペランドは 'num'タイプでなければならない ケースで_InternalLinkedHashMapを使用すると、次のエラーが発生するため、秒を一致させることはできません。ケース式は定数でなければなりません。

最後に、リストをintのリスト(List<int>)として定義しましたが、システムはそれを無視して単純なリストと見なします。 これは誤解を招くものであり、そのような宣言は禁じられるべきだと思います。

助け/提案?

+0

私はあなたがこれで強いモードから多くの助けを得ると思います。それはあなたにいくつかの警告/エラーを与えるだろう。 – Pacane

+0

型チェックのために 'is'を使います。 'if(type is List){...} else if(型がMap){...} else {...}'。 'switch'文はここでは機能しません。一般的なパラメータはチェックされません – Ganymede

答えて

3

あなたは、オブジェクトの型に基づいてフロー制御を行いたい場合は、実際にはオブジェクトのクラスは、それはタイプがある時間を実行しているもの、インタフェースをしませ実装しているかどうかに基づいて、それをやりたいです。これは、型テストオペレータisis!が対象です。

Dartでは、クラスもインターフェイスであるため、オブジェクトが特定のクラスであるかどうかをテストできます。

class Something { 
... 
} 

var s = new Something(); 
print(s is Something);  // true 

我々はそのようなListとしての「クラス」Mapとして考える傾向にある事が、クラスではないことに注意してください、彼らはインターフェイスです。そのような(コンストラクタを含む)インスタンスを返すものは、実際にはそのインタフェースを実装するクラスを返します。

ジェネリックは使用できますが、注意が必要です。

void main() { 

    var a = [1, 2, 'three']; 
    print(a is List);   // True 
    print(a is List<int>);  // True!!!! 
    print(a is List<String>); // True!!!! 

    var b = new List<int>.from([1, 2, 3]); 
    print(b is List);   // True 
    print(b is List<int>);  // True 
    print(b is List<String>); // False 
} 

クラスは、それを実装するクラスから、またはミックスインを介して継承、明示的に実装するためのインタフェースを実装することができます。

class Base { 
    void a() {} 
} 

class Mix { 
    void b() {} 
} 

class Mixed extends Base with Mix {} 

class Explicit implements Base { 
    void a() {} 
} 

void main() { 

    var c = new Mixed(); 
    print(c is Mixed);   // True 
    print(c is Base);   // True 
    print(c is Mix);   // True 

    var d = new Explicit(); 
    print(d is Base);   // True 
}