Golang - 具有零/空值的指针上的客户解组器/编组器
我正在尝试实现自定义UnmarshalJSON和MarshalJSON指针类型,但是当来自 json 的数据null/nil如下例所示时,不会调用此函数:
package main
import (
"encoding/json"
"fmt"
)
type A struct {
B *B `json:"b,omitempty"`
}
type B int
// Only for displaying value instead of
// pointer address when calling `fmt.Println`
func (b *B) String() string {
if b == nil {
return "nil"
}
return fmt.Sprintf("%d", *b)
}
// This function is not triggered when json
// data contains null instead of number value
func (b *B) UnmarshalJSON(data []byte) error {
fmt.Println("UnmarshalJSON on B called")
var value int
if err := json.Unmarshal(data, &value); err != nil {
return err
}
if value == 7 {
*b = B(3)
}
return nil
}
// This function is not triggered when `B`
// is pointer type and has `nil` value
func (b *B) MarshalJSON() ([]byte, error) {
fmt.Println("MarshalJSON on B called")
if b == nil {
return json.Marshal(0)
}
if *b == 3 {
return json.Marshal(7)
}
return json.Marshal(*b)
}
func main() {
var a A
// this won't call `UnmarshalJSON`
json.Unmarshal([]byte(`{ "b": null }`), &a)
fmt.Printf("a: %+v\n", a)
// this won't call `MarshalJSON`
b, _ := json.Marshal(a)
fmt.Printf("b: %s\n\n", string(b))
// this would call `UnmarshalJSON`
json.Unmarshal([]byte(`{ "b": 7 }`), &a)
fmt.Printf("a: %+v\n", a)
// this would call `MarshalJSON`
b, _ = json.Marshal(a)
fmt.Printf("b: %s\n\n", string(b))
}
输出:
a: {B:nil}
b: {}
UnmarshalJSON on B called
a: {B:3}
MarshalJSON on B called
b: {"b":7}
为什么UnmarshalJSON/MarshalJSON
不使用null/nil
指针类型的值调用
我们如何UnmarshalJSON/MarshalJSON
每次调用数据null/nil
和类型是指针而不是UnmarshalJSON/MarshalJSON
在A
类型上实现并b
从级别修改属性A
梦里花落0921
相关分类