![](/img/trans.png)
[英]Why does json.Unmarshal need a pointer to a map, if a map is a reference type?
[英]Why does json.Unmarshal work with reference but not pointer?
這個來自json.Unmarshal docs的示例(為簡單起見,略作修改以使用Animal
代替[]Animal
)有效,沒有錯誤:
// ...
var animals Animal
err := json.Unmarshal(jsonBlob, &animals)
// ...
但是這個經過稍微修改的示例卻沒有:
// ...
var animals *Animal
err := json.Unmarshal(jsonBlob, animals)
// ...
它顯示了這個晦澀的錯誤,實際上並沒有幫助(看起來更像是函數調用,而不是錯誤的IMO):
json:Unmarshal(nil * main.Animal)
這似乎是因為animals
是未初始化的指針。 但是文檔說(重點是我的):
Unmarshal將JSON解組為指針所指向的值。 如果指針為nil,則Unmarshal為其分配一個新值以使其指向。
那么,為什么在第二個示例中取消編組失敗並顯示出模糊的錯誤?
(此外,是“解組”還是“解組”(一個L)?文檔同時使用。)
您遇到了InvalidUnmarshalError (請參閱encode.go中的第109和110行 )。
// InvalidUnmarshalError描述了傳遞給Unmarshal的無效參數。
// (Unmarshal的參數必須是非nil指針。)
似乎文檔可以做些澄清,因為來自Unmarshal
來源的上面的引用和下面的注釋似乎相互矛盾。
如果指針為nil,則Unmarshal為其分配一個新值以使其指向。
因為您的指針為零。
如果您將其初始化,則可以正常運行: http : //play.golang.org/p/zprmV0O1fG
var animals *Animal = &Animal{}
另外,也可以用任何一種方式進行拼寫(盡管單個文檔中的一致性會很好): http : //en.wikipedia.org/wiki/Marshalling_(computer_science)
我認為問題在於,雖然您可以將指向nil的指針傳遞給Unmarshal(),但不能傳遞nil指針值 。
指向nil的指針將像:
var v interface{}
json.Unmarshal(text, &v)
v
值為nil,但指向v
的指針是一個非零的指針地址。 這是一個非零的指針,它指向一個nil接口{}(它本身是一個指針類型)。 在這種情況下,解組不會返回錯誤。
一個nil指針將像:
var v *interface{}
json.Unmarshal(text, v)
在這種情況下,v的類型是pointer to an interface{}
,但是與golang中var的任何聲明一樣, v
的初始值是該類型的零值。 所以v
是一個零值指針,這意味着它沒有指向內存中的任何有效位置。
如https://stackoverflow.com/a/20478917/387176中所述,json.Unmarshal()需要指向某物的有效指針,因此它可以在適當位置更改某物(無論是零值結構還是指針) 。
我以前有過類似的情況,但情況不同。 它與Go中的接口概念有關。 如果函數將接口聲明為參數或返回值, 則調用者必須傳遞或返回引用
在您的情況下, json.Unmarshal
接受接口作為第二個參數
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.