文章目录
前言
平时工作当中经常使用json的序列化或者反序列,但是偶尔也会发现你定义的结构体使用json序列化或者反序列化的时候不是你期望的结果,我也经常遇到这种,所以我通过读源码之后总结了一些可能让人诧异的操作,希望能规避一些错误场景,而且也会有源码解释的哦。我的所有的示例代码都是可以点击查看的哦,可以在The Go Playground
自己试试哦。
一、自定义序列化:MarshalJSON
下面代码你觉得结果是多少呢?{"MarshalJSON":"hit func MarshalJSON"}
吗?
代码如下:
type User struct {
Name string
Age int
Sex bool
}
func (u *User) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]string{
"MarshalJSON": "hit func MarshalJSON",
})
}
func main() {
var zhangSan = User{
Name: "Zhang San",
Age: 18,
Sex: true,
}
bytes, err := json.Marshal(zhangSan)
if err != nil {
fmt.Println("error:", err)
} else {
fmt.Println("result:", string(bytes))
}
}
运行得到的结果却是:
{
"Name":"Zhang San","Age":18,"Sex":true}
如何修正?
第7行方法的接受者User不使用指针即可得到正确结果,代码如下:
func (u User) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]string{
"MarshalJSON": "hit func MarshalJSON",
})
}
二、自定义序列化:TextMarshaler
我们对MarshalJSON很熟,但是自定义序列化还有另外一种方式:TextMarshaler接口,把结构体能序列化成文本格式,不一定是json格式的文本。
官方说明:
TextMarshaler is the interface implemented by an object that can
marshal itself into a textual form.
MarshalText encodes the receiver into UTF-8-encoded text and returns the result.
其实TextMarshaler也有MarshalJSON的问题,但是我这里想说的是当你的结构体同时实现了MarshalJSON和TextMarshaler之后,序列化的结果是什么呢?
代码如下:
type User struct {
Name string
Age int
Sex bool
}
func (u User) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]string{
"MarshalJSON": "hit func MarshalJSON",
})
}
func (u User) MarshalText() (text []byte, err error) {
return []byte(