在Go中,为什么JSON null有时不传递给解组JSON进行解码?
Go提供了在Go中,为什么JSON null有时不传递给解组JSON进行解码?,json,go,Json,Go,Go提供了编码/json.Unmarshaler接口,因此类型可以控制从json解码的方式。几乎在所有情况下,编码的JSON值都直接传递给UnmarshalJSON方法,但如果Unmarshaler是指针且JSON值为null,则不会传递。在这种情况下,指针被设置为nil,而根本不调用UnmarshalJSON。下面是一个例子: package main import ( "encoding/json" "fmt" ) type T string func (v *T) U
编码/json.Unmarshaler
接口,因此类型可以控制从json解码的方式。几乎在所有情况下,编码的JSON值都直接传递给UnmarshalJSON
方法,但如果Unmarshaler
是指针且JSON值为null
,则不会传递。在这种情况下,指针被设置为nil
,而根本不调用UnmarshalJSON
。下面是一个例子:
package main
import (
"encoding/json"
"fmt"
)
type T string
func (v *T) UnmarshalJSON(b []byte) error {
if b[0] == 'n' {
*v = "null"
} else {
*v = "not null"
}
return nil
}
func main() {
var a struct {
T T
PT1 *T
PT2 *T
}
a.PT1 = nil // just to be explicit
a.PT2 = new(T)
err := json.Unmarshal([]byte(`{"T":null,"PT1":"foo","PT2":null}`), &a)
if err != nil {
panic(err)
}
fmt.Printf("a.T is %#v\n", a.T)
if a.PT1 == nil {
fmt.Println("a.PT1 is nil")
} else {
fmt.Printf("a.PT1 points to %#v\n", *a.PT1)
}
if a.PT2 == nil {
fmt.Println("a.PT2 is nil")
} else {
fmt.Printf("a.PT2 points to %#v\n", *a.PT2)
}
}
我以为这会被打印出来
a.T为“空”
a、 PT1指向“非空”
a、 PT2指向“空”
相反,它会打印
a.T为“空”
a、 PT1指向“非空”
a、 PT2为零
因此
json.Unmarshal
为a.PT1
分配一个新的T
,它最初是nil
。但是它将a.PT2
设置为nil
,而不调用UnmarshalJSON
,即使a.PT2
不是nil
。为什么?这是因为将指针设置为nil
是处理JSONnull
的最常用方法,而*T
的解组JSON
方法本身无法做到这一点。如果在本例中调用了UnmarshalJSON
,则必须定义(**T).UnmarshalJSON
以将*T
设置为nil
。这将使最常见的情况变得非常尴尬
如果您不希望JSON
null
变成Gonil
,请不要使用指针。是的,如果您有JSON字符串“null”,您将获得引用类型的null值(在大多数语言中不是Go)。请不要问明显的问题,5分钟后自己回答。也许我比大多数人都笨,但我花了一天的大部分时间来弄清楚为什么这不是标准库中的bug。如果我没有使用专门设计用来覆盖默认解码规则的Go接口,那就很明显了。我不会走那么远。我的评论是基于你一问起就回答了这个问题。也许这对其他人会有帮助。我认为这是一个非常常见的事情,进入反序列化JSON虽然。