为什么 json.Unmarshal 使用引用而不是指针?

这个来自json.Unmarshal文档的例子(为了简单使用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)?文档同时使用了两者。)


qq_笑_17
浏览 288回答 3
3回答

慕侠2389804

您遇到了InvalidUnmarshalError(请参阅decode.go 中的第 109 和 110 行)。// InvalidUnmarshalError 描述了传递给 Unmarshal 的无效参数。// (Unmarshal 的参数必须是非 nil 指针。)似乎文档可以做一些澄清,因为上面的引用和下面来自Unmarshal来源的评论似乎相互矛盾。如果指针为 nil,则 Unmarshal 为其分配一个新值以指向它。

跃然一笑

我相信问题在于,虽然您可以将指向 nil的指针传递给 Unmarshal(),但您不能传递nil 指针 value。指向 nil 的指针类似于:var v interface{}json.Unmarshal(text, &v)的值为vnil,但指向的指针v是非零指针地址。它是一个非零指针,指向一个 nil interface{}(它本身是一个指针类型)。在这种情况下,解组不会返回错误。一个 nil 指针是这样的:var v *interface{}json.Unmarshal(text, v)在这种情况下, v 的类型是pointer to an interface{},但与 golang 中 var 的任何声明一样, 的初始值v是该类型的零值。所以v是一个零值指针,这意味着它不指向内存中任何有效的地方。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go