如何初始化 from_json 在 Crystal 中创建的对象

How to initialize an object created by from_json in Crystal

看看这个例子:https://play.crystal-lang.org/#/r/4hqb

这是代码(不知道 link 适合多长时间...)

require "json"

class House
  JSON.mapping(address: String)

  getter first_part

  def initialize
    @first_part = address.split(" ")[0]
  end
end

house = House.from_json(%({"address": "Crystal Road 1234"))
puts house.first_part

这是文档中 JSON.mapping 示例的基础知识。除了我添加了一个 initialize 它对 JSON 数据(地址)做了一些事情。

麻烦的是我们得到这个错误:

Error in line 8: this 'initialize' doesn't explicitly initialize instance variable '@address' of House, rendering it nilable

问题:

到目前为止,这就是我的想法。我不喜欢它,但它实现了我想要的。两个关键的事情是:

  1. 您必须在初始化中使用 previous_def 并使用正确的 arg(PullParser 类型)
  2. 您必须使用 "catch-all initialization"
  3. 将值初始化为您想要的类型

两者都记录在此处:https://crystal-lang.org/docs/syntax_and_semantics/methods_and_instance_variables.html

class House
  @first_part = ""

  JSON.mapping(
    address: {type: String, nilable: false}
  )

  getter first_part

  def initialize(pull : JSON::PullParser)
    previous_def
    @first_part = address.split(" ")[0]
  end

end

house = House.from_json(%({"address": "Crystal Road 1234"}))
puts house.first_part

注意:我说我不喜欢因为我感觉喜欢定义@first_part 我在下面做的方式保证它将是一个字符串,并且 previous_def 调用应该只是将代码粘贴到 JSON.mapping 宏定义的初始化程序中。相反,由于这两个定义,我们得到一个错误,即 @first_part 在初始化方法的 all 中未正确初始化。