gpt4 book ai didi

pointers - json.Unmarshal() 接受指向指针的指针

转载 作者:IT王子 更新时间:2023-10-29 01:18:28 26 4
gpt4 key购买 nike

我意外地注意到,我可以成功地将一个指向结构的指针和一个指向指向结构的指针的指针传递给 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")
}
}

我真的很惊讶第二个(unmarshal to **Person)有效。

json.Unmarshal() 发生了什么?它是否在找到结构之前取消对指针的引用?

文档提供:

To unmarshal JSON into a pointer, Unmarshal first handles the case of the JSON being the JSON literal null. In that case, Unmarshal sets the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into the value pointed at by the pointer

似乎做的还不止这些。到底发生了什么?

进一步充实我的问题:它怎么知道自动取消对指针的引用?该文档说它将“解码为指针指向的值”。由于我的指针的值实际上是另一个指针,并且没有 Name/Age 字段,我希望它就此停止。

明确一点:我并不是说 Unmarshal() 中存在错误或功能不当;我试图让我惊讶的是,当给定一个 ptr-to-ptr 时它完全可以工作,并避免在我使用它时出现任何潜在的陷阱。

最佳答案

json 包没有理由“停在指针处”,因为指针在 json 中没有任何意义。它必须不断遍历树才能找到要写入的值。由于 json 包将允许将相同的值解码为 Type*Type,因此它应该能够将其解码为 **类型,这也是 Go 中的有效类型。

例如,如果 Person 是使用指针定义的,以区分 nil 和零值,并且您正在解码成 []*Person 的 slice ,则 json包需要遵循这些指针,并在必要时分配值。如果 Person 中的字段定义为 **string,这同样适用。

type Person struct {
Name **string
Age *int
}

type People []*Person

http://play.golang.org/p/vLq0nJPG5M

关于pointers - json.Unmarshal() 接受指向指针的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35604356/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com