一个golang 指针问题请教?

package main

import(
        "fmt"
)

type PluginInfo struct{
        Id      int
        Name    string
}

func main(){
        info := make([]*PluginInfo,0)

        pluginMap := make(map[int]PluginInfo)
        pluginMap[1] = PluginInfo{
                Id:1,
                Name:"aa",
        }
        pluginMap[2] = PluginInfo{
                Id:2,
                Name:"bb",
        }

        for i, tmp := range pluginMap {
                fmt.Println(i, &tmp)//打印出得数据没有问题
                info = append(info, &tmp) //info中的地址数据竟然是相同的
        }
        fmt.Println(info)

        for _, tmp := range info {
                fmt.Println(*tmp)
        }

}

为什么打印最后的info,会是两个相同结果呢都是{2 bb} ?

阅读 3.3k
3 个回答

作用域的问题,这里的i和tmp的作用域只在for语句块之内,tmp在for语句内只使用一个内存地址空间,每次循环,都把新值赋到同一个地址上,所以打印值是有区别的,但取地址却是同一个。
可以这样修改:

    ....
    pluginMap := make(map[int]*PluginInfo)
    pluginMap[1] = &PluginInfo{
            Id:1,
            Name:"aa",
    }
    pluginMap[2] = &PluginInfo{
            Id:2,
            Name:"bb",
    }

    for i, tmp := range pluginMap {
            fmt.Println(i, *tmp)
            info = append(info, tmp)
    }
    ....

原因其他答案已经说清楚了,就是 tmp 变量的值一直在改变,最终使用的是 tmp 的最后的值

有一个简单的方案。

    for i, tmp := range pluginMap {
        fmt.Println(i, &tmp) //打印出得数据没有问题
        tmp := tmp  // 增加这行就可以了。
        info = append(info, &tmp) //info中的地址数据竟然是相同的
    }

tmp地址是相同的, 添加到info数组的对象的地址都指向同一块内存.

for _, tmp := range pluginMap {
        fmt.Printf("address: %p\n", &tmp)  // print address
}

address: 0xc820076080
address: 0xc820076080
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题