首页 >后端开发 >Golang >为什么使用'interface{}”时'json.Unmarshal”会意外更改我的结构?

为什么使用'interface{}”时'json.Unmarshal”会意外更改我的结构?

Barbara Streisand
Barbara Streisand原创
2024-12-12 19:53:11232浏览

Why Does `json.Unmarshal` Unexpectedly Change My Struct When Using `interface{}`?

关于 Go 的 interface{} 类型的误解

背景

interface{} 类型是 Go 编程的一个重要方面,它允许动态处理值,但它的使用常常会导致误解。

一个意外的错误json.Unmarshal

使用 interface{} 作为函数参数并遇到 json.Unmarshal 问题时,会出现一个常见的误解。以下代码片段演示了此错误:

func test(i interface{}) {
    j := []byte(`{ "foo": "bar" }`)
    fmt.Printf("%T\n", i)
    fmt.Printf("%T\n", &i)
    json.Unmarshal(j, &i)
    fmt.Printf("%T\n", i)
}

func main() {
    test(Test{})
}

type Test struct {
    Foo string
}

运行时,此代码在解组后意外地将 struct Test{} 转换为 map[string]interface{},如输出中所示:

main.Test
*interface {}
map[string]interface {}

理解误解

误解在于 interface{} 类型的本质。它不像某些人想象的那样是一个空容器,而是值类型对的包装器。当非指针 Test{} 传递给 test() 时,json.Unmarshal 函数需要一个指针,从而导致它创建一个新的 map[string]interface{} 值。

解决此问题,必须传递一个指向interface{}参数的指针。

func test(i interface{}) {
    j := []byte(`{ "foo": "bar" }`)
    fmt.Printf("%T\n", i)
    fmt.Printf("%T\n", &i)
    json.Unmarshal(j, i)
    fmt.Printf("%T\n", i)
    fmt.Println(i)
}

func main() {
    test(&Test{})
}

这一修改确保将指向指针的指针传递给函数,从而允许 json.Unmarshal正确解组 JSON 数据。

结论

记住,interface{} 需要谨慎使用以避免意外行为,这一点至关重要。了解其底层实现及其对 json.Unmarshal 等函数的影响对于有效的 Go 开发至关重要。

以上是为什么使用'interface{}”时'json.Unmarshal”会意外更改我的结构?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn