登录
首页 >  Golang >  Go问答

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

来源:stackoverflow

时间:2024-02-24 08:57:26 165浏览 收藏

学习Golang要努力,但是不要急!今天的这篇文章《正确的自定义类型声明 UnmarshalJSON 的方法是什么?》将会介绍到等等知识点,如果你想深入学习Golang,可以关注我!我会持续更新相关文章的,希望对大家都能有所帮助!

问题内容

我用其他语言(如 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上试试。

今天关于《正确的自定义类型声明 UnmarshalJSON 的方法是什么?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>