gpt4 book ai didi

json - 为自定义类型声明 UnmarshalJSON 的正确方法是什么?

转载 作者:行者123 更新时间:2023-12-03 10:10:47 26 4
gpt4 key购买 nike

我在其他语言(如 Java)中创建自己的类型作为枚举值。我为此类型实现了反序列化 UnmarshalJSON 方法,发现 marshal 无法转换为自定义类型

package main

import (
"encoding/json"
"fmt"
)

type Mode string

const (
UPDATE Mode = "update"
INSERT Mode = "insert"
)
func (receiver Mode) String() string {
switch receiver {
case UPDATE:
return string(UPDATE)
case INSERT:
return string(INSERT)
default:
return "UNRECOGNIZED"
}
}
func (receiver Mode) MarshalJSON() ([]byte, error) {
return []byte(`"` + receiver.String() + `"`), nil
}
func (receiver Mode) UnmarshalJSON(data []byte) error {
receiver = Mode(data[1 : len(data)-1])
return nil
}

func main() {
var source Mode = "update"
tmp, err := json.Marshal(source)
if err != nil {
panic(err)
}
var received Mode

err = json.Unmarshal(tmp, &received)
if err != nil {
panic(err)
}

fmt.Println("source: ", source, "; received: ", received)
}

并查看输出:source: update ;收到:无法识别。如何以正确的方式为这种类型编写 UnmarshalJSON?

最佳答案

Unmarshal() 必须修改接收器,所以它必须是一个指针,请看这个工作示例:

func (receiver *Mode) UnmarshalJSON(data []byte) error {
*receiver = Mode(data[1 : len(data)-1])
return nil
}

这将输出(在 Go Playground 上尝试):

source:  update ; received:  update

参见相关问题:How to json unmarshalling with custom attribute type in Go

此外,您不应该自己处理生成/解析 string,不能保证输入是有效的 JSON string,也不能保证您没有处理正确的转义。留给 encoding/json包。

所以宁愿使用这个实现:

func (receiver Mode) MarshalJSON() ([]byte, error) {
return json.Marshal(receiver.String())
}

func (receiver *Mode) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
*receiver = Mode(s)
return nil
}

这将处理无效输入并始终生成有效的 JSON 输出。它输出相同,在 Go Playground 上试试.

关于json - 为自定义类型声明 UnmarshalJSON 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65275654/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com