为什么在取消引用之前必须复制字符串?

要将值是字符串的映射转换为值是字符串的映射,我需要先复制字符串。如果我不同意,那么所有值都是相同的,可能是错误的值。为什么是这样?我不在这里使用字符串文字的地址。

func mapConvert (m map[string]string) map[string]*string {
    ret := make(map[string]*string)

    for k, v := range m {
        v2 := v[:]
        ret[k] = &v2
        // With the following instead of the last 2 lines, the returned map have the same, sometimes wrong value for all keys
        //ret[k]=&v 
    }
    return ret
}
评论
  • eet
    eet 回复

    您没有显示原始代码,但可能看起来像这样:

    func mapConvert (m map[string]string) map[string]*string {
        ret := make(map[string]*string)
    
        for k, v := range m {
            ret[k] = &v
        }
        return ret
    }
    

    There is a single variable v in this function. The address of that single variable is used as the value for every key in the map.

    使用此代码:

    func mapConvert (m map[string]string) map[string]*string {
        ret := make(map[string]*string)
    
        for k, v := range m {
            v := v
            ret[k] = &v
        }
        return ret
    }
    

    该函数在循环内声明一个新变量,并将该变量的地址添加到映射中。

    See https://golang.org/doc/faq#closures_and_goroutines for an explanation of the same problem in the context of concurrency.