簡體   English   中英

為什么json.Unmarshal使用引用而不使用指針?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM