如何使用 JSON::Serializable 迭代和静态键入值?

how to iterate and statically type values using JSON::Serializable?

我有以下代码

require "json"

struct TreeData
  include JSON::Serializable
  include JSON::Serializable::Unmapped

  @increased_hp_percent : Float32?
  @value : Float32?
  @increased_strength : Float32?

end


puts TreeData.from_json(%({"1":{},"2":{"modifications":{"increased_hp_percent":5},"value":5},"3":{"value":10},"4":{"modifications":{"increased_hp_percent":15,"increased_strength":20}}}))

产生以下输出:

TreeData(@json_unmapped={"1" => {}, "2" => {"modifications" => {"increased_hp_percent" => 5_i64}, "value" => 5_i64}, "3" => {"value" => 10_i64}, "4" => {"modifications" => {"increased_hp_percent" => 15_i64, "increased_strength" => 20_i64}}}, @increased_hp_percent=nil, @value=nil, @increased_strength=nil)

基本上,我想将我指定的键(increased_hp_percentvalueincreased_strength)的值设置为Float32

但是,它们没有设置为正确的类型。我相信这是因为它们在另一个 json 对象中。

我也在尝试遍历 json。如果我要使用 JSON.parse,那么使用 json.as_h.each 就可以了。我不知道如何使用新的 JSON::Serializable

您可能会问我为什么不直接使用 JSON.parse?好吧,因为我想将我的 json 静态键入正确的类型。但我也希望能够像以前一样通过它进行枚举。

您必须为嵌套数据结构正确创建类型,它不会尝试为您挖掘它们:

require "json"

struct Modifications
  include JSON::Serializable

  getter increased_hp_percent : Float32?
  getter increased_strength : Float32?
end

struct TreeData
  include JSON::Serializable

  getter modifications : Modifications?
  getter value : Float32?
end

data = Hash(String, TreeData).from_json(%({"1":{},"2":{"modifications":{"increased_hp_percent":5},"value":5},"3":{"value":10},"4":{"modifications":{"increased_hp_percent":15,"increased_strength":20}}}))

data.each_value do |node|
  pp node
end

输出:

TreeData(@modifications=nil, @value=nil)
TreeData(
 @modifications=
  Modifications(@increased_hp_percent=5.0_f32, @increased_strength=nil),
 @value=5.0_f32)
TreeData(@modifications=nil, @value=10.0_f32)
TreeData(
 @modifications=
  Modifications(@increased_hp_percent=15.0_f32, @increased_strength=20.0_f32),
 @value=nil)