为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Go 中使用自定义属性类型进行 json 解组

如何在 Go 中使用自定义属性类型进行 json 解组

Go
万千封印 2023-07-26 10:10:40
在我的项目中,我定义了结构以便从 JSON 获取数据。我尝试使用json.Unmarshal()函数。但它不适用于自定义类型属性。有一个这样的结构:type TestModel struct {    ID   NullInt `json:"id"`    Name string  `json:"name"`}在那里,NullInt类型是通过MarshalJSON()和UnmarshalJSON()函数的实现来定义的:// NullInt ...type NullInt struct {    Int   int    Valid bool}// MarshalJSON ...func (ni NullInt) MarshalJSON() ([]byte, error) {    if !ni.Valid {        return []byte("null"), nil    }    return json.Marshal(ni.Int)}// UnmarshalJSON ...func (ni NullInt) UnmarshalJSON(b []byte) error {    fmt.Println("UnmarshalJSON...")    err := json.Unmarshal(b, &ni.Int)    ni.Valid = (err == nil)    fmt.Println("NullInt:", ni)    return err}在main()功能上,我实现了:func main() {    model := new(TestModel)    JSON := `{        "id": 1,        "name": "model"     }`    json.Unmarshal([]byte(JSON), &model)    fmt.Println("model.ID:", model.ID) }在控制台中,我得到:UnmarshalJSON...NullInt: {1 true}model.ID: {0 false}正如您所看到的,NullInt.UnmarshalJSON()被调用并且ni是我所期望的但model.ID值。 实现功能的正确方法是什么UnmarshalJSON()?另外,当我设置:(JSON := `{"name": "model"}`没有id)时,控制台只是:model.ID: {0 false}这意味着,该UnmarshalJSON()函数没有被调用,然后我没有model.ID以正确的方式获得 的值。
查看完整描述

1 回答

?
胡子哥哥

TA贡献1825条经验 获得超6个赞

UnmarshalJSON()需要修改接收者,所以必须使用指针接收者:


func (ni *NullInt) UnmarshalJSON(b []byte) error {

    // ...

}

接收者和所有参数只是副本,如果不使用指针,则只能修改副本,该副本在方法返回后将被丢弃。如果您使用指针接收器,那也只是一个副本,但指向的值将是相同的,因此您可以修改原始(指向)对象。


为了保持一致性,其他方法也使用指针接收器。


通过此更改,它可以工作并输出(在Go Playground上尝试):


UnmarshalJSON...

NullInt: &{1 true}

model.ID: {1 true}


查看完整回答
反对 回复 2023-07-26
  • 1 回答
  • 0 关注
  • 101 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信