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

在我的项目中,我定义了结构以便从 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以正确的方式获得 的值。


万千封印
浏览 102回答 1
1回答

胡子哥哥

UnmarshalJSON()需要修改接收者,所以必须使用指针接收者:func (ni *NullInt) UnmarshalJSON(b []byte) error {    // ...}接收者和所有参数只是副本,如果不使用指针,则只能修改副本,该副本在方法返回后将被丢弃。如果您使用指针接收器,那也只是一个副本,但指向的值将是相同的,因此您可以修改原始(指向)对象。为了保持一致性,其他方法也使用指针接收器。通过此更改,它可以工作并输出(在Go Playground上尝试):UnmarshalJSON...NullInt: &{1 true}model.ID: {1 true}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go