【发布时间】:2016-06-06 20:57:03
【问题描述】:
我很偶然地注意到,我可以成功地将指向结构的指针和指向结构指针的指针传递给json.Unmarshal(),并且都可以正常工作:
package main
import (
"testing"
"encoding/json"
)
type Person struct {
Name string
Age int
}
func TestMarshaling(t *testing.T) {
foo := &Person{Name: "bob", Age: 23}
// marshal it to bytes
b, err := json.Marshal(foo)
if err != nil {
t.Error(err)
}
bar := &Person{} // pointer to new, empty struct
err = json.Unmarshal(b, bar) // unmarshal to bar, which is a *Person
if err != nil {
t.Error(err)
}
testBob(t, bar) // ok
bar = &Person{} // pointer to new, empty struct
err = json.Unmarshal(b, &bar) // wait a minute, passing in a **Person, yet it still works?
if err != nil {
t.Error(err)
}
testBob(t, bar) // ok
}
func testBob(t *testing.T, person *Person) {
if person.Name != "bob" || person.Age != 23 {
t.Error("not equal")
}
}
我真的很惊讶第二个(解组到**Person)起作用了。
json.Unmarshal() 发生了什么?它是否在找到结构之前取消引用指针?
文档提供:
为了将 JSON 解组为指针,Unmarshal 首先处理以下情况 JSON 是 JSON 文字 null。在这种情况下,Unmarshal 设置 指向零的指针。否则,Unmarshal 将 JSON 解组到 指针指向的值
它的作用似乎不止于此。到底发生了什么?
更多地充实我的问题:它如何知道自动将我的指针取消引用到指针?文档说它将解组“到指针指向的值”。由于我的指针的值实际上是另一个指针,并且没有 Name/Age 字段,我希望它停在那里。
明确一点:我并不是说Unmarshal() 中存在错误或错误功能;我试图让我感到惊讶的是,当给定一个 ptr-to-ptr 时它完全可以工作,并避免在我使用它时出现任何潜在的陷阱。
【问题讨论】:
-
解码器必须跟随指针,并根据需要分配内部指针。这样做的结果是它将遵循多个级别的指针。除了您已经提供的答案之外,还有什么问题?
-
我试着充实一点。
-
:) 它does not stop 多了一层