[英]In Go, why is JSON null sometimes not passed to UnmarshalJSON for decoding?
Go 提供了encoding/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 is "null"
a.PT1 points to "not null"
a.PT2 points to "null"
相反,它打印
a.T is "null"
a.PT1 points to "not null"
a.PT2 is nil
所以json.Unmarshal
分配一個新的T
的a.PT1
,其最初是nil
。 但是它在不調用UnmarshalJSON
情況下將a.PT2
設置為nil
,即使a.PT2
不是nil
。 為什么?
這是因為將指針設置為nil
是處理 JSON null
的最常用方法,並且*T
的UnmarshalJSON
方法無法自行執行此操作。 如果在這種情況下調用UnmarshalJSON
則必須定義(**T).UnmarshalJSON
以將*T
設置為nil
。 這會使最常見的情況變得非常尷尬。
如果您不希望 JSON null
變為 Go nil
,請不要使用指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.