2016-07-25 5 views
2

Я определил данные объекта, которые я использую для хранения различных бит данных, которые я использую для своего кода. Я хочу вставить новую комнату во время выполнения. Например, новый ключ «R200» из переменной, но пока еще не выполнен.haxe добавить новый ключ к объекту с переменной

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

Haxe-х anonymous structures являются не более чем нетипизированных, организованных коллекций данных. Их структура неизменна после установки, и только значения свойств могут быть изменены. Доступ к массиву (нотация нот) не определен в анонимных структурах - вместо этого используется точечная нотация.

Из-за нетипизированного (динамического) характера анонимных структур они могут иметь negative impact on performance при компиляции статических целей.

Рекомендуется организовывать и печатать анонимные структуры с использованием typedefs и typedef extensions. Это обеспечивает безопасность типов и помогает серверу компиляции подхватывать любые печатные ошибки на ходу.

Чтобы вернуться к точке, то, что вы пытаетесь сделать, лучше всего использовать с помощью maps и typedefs. Карты позволяют хранить правильные пары ключ-значение - как с помощью методов, так и с помощью скобок - и typedefs позволяют вводить структуру данных, обеспечивая безопасность типов.

Имея это в виду, ваш фрагмент кода может быть воссоздан следующим образом:

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 для получения дополнительной информации.


Edit (2016-07-26)

Ответ предоставляется lordkryss вполне допустимо. Однако есть две основные причины, по которым я не поднял reflection.

  • Отражение - это функция времени исполнения, ее использование излишне усложняет ваш код и не предлагает вам желаемого синтаксиса.
  • Отражение может быть дорогостоящим и непредсказуемым для разных целей.

Как правило, вам следует лучше двигаться с учетом динамических, а не статических целей. Помните об этом при разработке своего проекта и определении того, какой будет ваша целевая платформа.

Я рекомендую смотреть в сгенерированные источники, чтобы лучше понять влияние отражения. Вы можете использовать официальную песочницу try.haxe.org, чтобы увидеть исходный код JavaScript, генерируемый Haxe 3.2.0. Существует также unofficial sandbox, который также позволяет вам увидеть исходный код JavaScript Haxe 3.3.0-rc.1.

Лично, Я не думаю, что отражение является приемлемым решением вашей проблемы.. Я вижу вашу проблему как одно из поиска соответствующей структуры данных для представления ваших данных. Отражение имеет свое применение, но я бы не рекомендовал его в этом случае.

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

Вы можете попробовать код на try.haxe.org

+0

Спасибо, ребята, все эти ответы являются большими. На данный момент я пришел с ответом LordKryss, потому что его проще всего реализовать, но он вернется и посмотрит на правильную структуру, когда я ее запустил. Спасибо, ребята – Ferrari177

3

Рассмотрите возможность использования haxe.DynamicAccess это оболочка времени компиляции для 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

Это на самом деле не вопрос, но, чтобы избежать отражения полностью, вы можете использовать массив вместо объекта. Это архитектурное изменение, выбор для его использования зависит в основном от того, сколько вы хотите искать в номере по его идентификатору. Если это довольно часто, используйте карту, иначе это можно рассмотреть.

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