如何初始化 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
问题:
- 映射中的默认值是 'nilable: false',我不希望它是 nilable。有什么方法可以预期此错误来自 JSON 未能指定地址而不是将其设为可空字段?
- 似乎我应该重写(并调用 super)的某个地方还有另一个初始化,但到目前为止我还没有成功。如果这是正确的方法,它是如何完成的?
到目前为止,这就是我的想法。我不喜欢它,但它实现了我想要的。两个关键的事情是:
- 您必须在初始化中使用 previous_def 并使用正确的 arg(PullParser 类型)
- 您必须使用 "catch-all initialization"
将值初始化为您想要的类型
两者都记录在此处: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 中未正确初始化。
看看这个例子: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
问题:
- 映射中的默认值是 'nilable: false',我不希望它是 nilable。有什么方法可以预期此错误来自 JSON 未能指定地址而不是将其设为可空字段?
- 似乎我应该重写(并调用 super)的某个地方还有另一个初始化,但到目前为止我还没有成功。如果这是正确的方法,它是如何完成的?
到目前为止,这就是我的想法。我不喜欢它,但它实现了我想要的。两个关键的事情是:
- 您必须在初始化中使用 previous_def 并使用正确的 arg(PullParser 类型)
- 您必须使用 "catch-all initialization" 将值初始化为您想要的类型
两者都记录在此处: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 中未正确初始化。