Golang -客户解封器/封送器在指针上为nil/null值
我试图在指针类型上实现自定义的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/nilnull/nil且类型为指针时如何调用A,而不是在A类型上实现UnmarshalJSON/MarshalJSON,并从A级别修改b属性发布于 2022-09-30 09:29:18
,简称
目前,解除封送/封送Go结构只会发出非零字段,因为nil pointer是一个Go值为零,所以在本例中不调用UnmarshalJSON/MarshalJSON。
此外,似乎有一些相关的建议。
然而,现在还没有解决办法。
每个代码的 解组员
解编组器将UnmarshalJSON([]字节(“null”))实现为无操作。
// By convention, to approximate the behavior of Unmarshal itself,
// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
type Unmarshaler interface {
UnmarshalJSON([]byte) error
}https://stackoverflow.com/questions/73901013
复制相似问题