Go语言指针疑问:JSON解析传f输出nil,传&f正常的原因?
为什么Go语言中
json.Unmarshal传f和&f结果不同? 这事儿本质是Go的值传递机制加上json.Unmarshal的工作要求导致的,我给你掰明白:
先看json.Unmarshal的核心要求
json.Unmarshal的函数签名是这样的:
func Unmarshal(data []byte, v interface{}) error
它的第二个参数v必须是一个指针类型——因为这个函数需要把解析后的JSON数据写入到你传入的变量里,而要修改一个变量的内容,在Go里必须拿到它的内存地址(也就是指针)。
第一种情况:传f为什么输出nil?
你写的代码里:
var f interface{} json.Unmarshal([]byte(str), f)
这里的f是一个初始值为nil的interface{}变量。因为Go是值传递,当你把f传给Unmarshal时,函数会收到一个f的副本——也就是另一个nil的interface{}。
函数内部就算把解析后的JSON数据写到这个副本里,也和原来的f半毛钱关系都没有。函数执行完,副本被销毁,原来的f还是初始的nil,所以打印出来就是nil。
第二种情况:传&f为什么能正常工作?
当你改成:
json.Unmarshal([]byte(str), &f)
这时候你传给Unmarshal的是f的内存地址,也就是一个*interface{}类型的指针。函数拿到这个指针后,就能直接找到原来的f变量所在的内存区域,把解析后的JSON数据直接写进去。
等函数执行完,原来的f已经被正确赋值了,自然就能打印出JSON内容。
一句话总结
想让json.Unmarshal修改你的变量,就得给它这个变量的指针,不然它只能修改一个无关的副本,你的变量还是原样。这就像你要让快递员把东西放进你家,得给人家你家地址,而不是给人家一个空盒子的副本~
内容的提问来源于stack exchange,提问作者hguser
相关产品推荐
相关产品推荐

