2016-07-25 6 views
2

私は自分のコードに使用するさまざまなデータを格納するために使用するオブジェクトデータを定義しました。私は実行時に新しい部屋を挿入したい。たとえば、変数から新しいキー「R200」を作成しますが、今までできなかったキーです。 haXeののanonymous structureshaxe変数付きオブジェクトに新しいキーを追加

static public var data = 
{ 
    room: { 
     "R100": {monstersLeft: 2 } 
    } 
} 


// need to add the the object data : 
// would like to reference is like: 
var newRoom = "R200"; 
???? data[newRoom ].monstersLeft = 5; 

trace(data.R200.monstersLeft) 

答えて

4

は、データの型なし、整理コレクション以上のものではありません。それらの構造は設定されると不変であり、プロパティ値のみを変更することができます。配列アクセス(かっこ表記)は匿名の構造体では定義されていません。代わりにドット表記が使用されます。

匿名構造の型指定されていない(動的)性質のため、静的ターゲットにコンパイルするときにはnegative impact on performanceを持つことができます。

typedefstypedef extensionsを使用して匿名構造を整理して入力することをお勧めします。これにより、型の安全性が保証され、コンパイルサーバーは移動中の入力ミスを拾うのに役立ちます。

ポイントを取り戻すには、mapsとtypedefを使用してください。マップでは、メソッドと括弧表記の両方で適切なキーと値のペアを格納できます。また、typedefを使用すると、データ構造を入力して型の安全性を確保できます。念頭に置いて

次のように、あなたのコードスニペットを再作成することができます

class Test { 
    static var data : Map<String, Room> = new Map<String, Room>(); 

    static function main() { 
     data["R100"] = { monsterCount: 5 }; 
     data["R200"] = { monsterCount: 10 }; 

     trace(data["R100"].monsterCount); 
     trace(data["R200"].monsterCount); 
    } 
} 

typedef Room = { 
    var monsterCount : Int; 
} 

Roomは今{ "monsterCount": (Int) }データ構造によって記述されたタイプで、部屋のIDを表す文字列キーにマップされます。

マップAPIを使用すると、キー/値のペアをマップしたり、繰り返したりすることができます。詳細についてはAPI docsを確認してください。 lordkryssによって提供さ


編集(2016年7月26日)

答えは完全に有効です。しかし、私がreflectionを育てなかった主な理由が2つあります。

  • リフレクションはランタイム機能であり、その使用は不必要にコードを複雑にし、必要な構文を提供しません。
  • 反射は、異なるターゲットで高価で予測できないことがあります。

通常、静的なターゲットではなくダイナミックでリフレクションする方がよいでしょう。プロジェクトを開発し、ターゲットプラットフォームを決定する際には、そのことを念頭に置いてください。

反射の影響をよりよく理解するために、生成されたソースを調べることをおすすめします。あなたは公式のtry.haxe.orgサンドボックスを使って、Haxe 3.2.0で生成されたJavaScriptのソースコードを見ることができます。 unofficial sandboxもあり、Haxe 3.3.0-rc.1で生成されたJavaScriptのソースコードを見ることができます。

個人的には、私はリフレクションがあなたの問題に対して許容可能な解決策であるとは思わない。私はあなたの問題を、あなたのデータを表現するための適切なデータ構造を見つけることの一つとして見ています。反射には用途がありますが、私はこの場合は勧めません。

2

Domagojのソリューションは、おそらくあなたの問題へのよりよい解決策ですが、あなたが実際にあなたがReflectionを使用して、質問に尋ねる何ができる:

class Test { 
    static public var data = 
    { 
     room: { 
      "R100": {monstersLeft: 2 } 
     } 
    } 



    static function main() { 
     var newRoom = "R200"; 
     Reflect.setField(data,newRoom,{monstersLeft:5}); 
     trace(Reflect.getProperty(data, newRoom).monstersLeft); 
    } 
} 

あなたはhaxe.DynamicAccessを使用することを検討してtry.haxe.org

+0

おかげでみんなは、これらすべての答えは素晴らしいです。私はLordKryssの答えを今すぐに持ってきました。なぜなら、実装するのが最も簡単だからですが、実行したときに正しい構造を入れてみることに戻ります。ありがとうGuys – Ferrari177

3

でコードを試すことができますこれはReflectのコンパイル時のラッパーです。したがって、ランタイムオーバーヘッドは追加されませんが、匿名構造を操作するための便利な構文が提供されます。

import haxe.DynamicAccess; 

typedef TRoom = { 
    monstersLeft : Int 
} 


class Test { 
    static public var data : {room:DynamicAccess<TRoom>} = { 
     room: { 
      "R100": {monstersLeft: 2} 
     } 
    }; 


    static function main() { 

     var newRoom = "R200"; 
     data.room[newRoom] = {monstersLeft:10}; 

     trace(data.room['R200'].monstersLeft); 
    } 
} 

あなたはここでそれを試すことができます。http://try.haxe.org/#cBc45

+0

私はそれがコンパイル時だとは思わない、すべての反映は実行時に行われます。リフレクションのようなものをエミュレートするには、マクロを使用する必要があります。 – Chii

+0

私はリフレクションの上に追加のオーバーヘッドがありません。 – RealyUniqueName

0

をそれはあなたが:)地図は次のように構築されなければならない何をしたいですので、あなたはまた、このためStringMapを使用することができます:[key => value, key => value ..]。このタイプのマップにはarray accessがあります。このマップは、求めた構文を示します。

class Test { 
    static public var data = { 
     rooms: [ 
      "R100" => {monstersLeft: 2} 
     ] 
    } 

    static function main() { 
     // add room 
     data.rooms["R200"] = {monstersLeft: 5}; 

     // read room 
     trace(data.rooms["R100"].monstersLeft); // 2 
    } 
} 

デモ:http://try.haxe.org/#2B855

これは本当に問題ではなく、完全にあなたの代わりにオブジェクトの配列を使用することができます反射を避けるために。これはアーキテクチャ上の変更です。使用する選択は、そのIDで部屋をどれだけ検索したいかによって決まります。それが非常に頻繁な場合は、マップを使用します。そうでない場合は、これが考慮されます。

class Test { 
    static public var data = { 
     rooms: [ 
      {id:"R100", monstersLeft: 2}, 
     ] 
    } 

    static function main() { 
     // add room 
     var newRoom = {id:"R200", monstersLeft: 5}; 
     data.rooms.push(newRoom); 

     // find rooms 
     var room100 = findRoom("R100"); 
     trace(room100.monstersLeft); // 2 
    } 

    static function findRoom(id:String) { 
     for (room in data.rooms) if (room.id == id) return room; 
     return null; 
    } 
} 

デモ:http://try.haxe.org/#8bFfD

関連する問題