【问题标题】:Copy array of strings to array of string pointers将字符串数组复制到字符串指针数组
【发布时间】:2020-11-04 17:16:42
【问题描述】:

我正在尝试将字符串数组复制到字符串指针数组中

但在范围的末尾,我看到目标数组中的所有元素都指向源数组中的最后一个元素。

我是新手,想正确理解幕后发生的事情。

这里是重现问题的代码sn-p

emails := []string{"a", "b"}
CCEmails := []*string{}
for _, cc := range emails {
    CCEmails = append(CCEmails,&cc)
}
fmt.Println(CCEmails)

https://play.golang.org/p/i6zJqoA4qAc

【问题讨论】:

  • 将代码放入问题中,而不是链接到它。
  • Go range 循环 reuse 迭代变量,因此为了避免您看到的问题,您首先需要在循环内创建迭代变量的副本,然后使用它的指针添加到结果数组/切片中。
  • @mkopriva 听起来像是值得发布的答案。
  • 谁投了反对票,你能解释一下原因吗?

标签: arrays pointers go


【解决方案1】:

要了解幕后发生的事情,您必须了解 go 中 for range 构造的指针和值语义。

在这个ardan labs article里解释的很清楚

    emails := []string{"a", "b"}
        CCEmails := []*string{}
        for _, cc := range emails {
                
                p := &cc
            fmt.Println(cc, p)
            CCEmails = append(CCEmails,&cc)
        }

上面的代码遵循值语义。它复制原始切片并迭代切片内的值。在迭代时,它会复制指针处特定索引处的值。 Atlast,指针指向迭代完成后的最后一个元素。

要获得所需的行为,请使用指针语义 -

emails := []string{"a", "b"}
    CCEmails := []*string{}
    for i := range emails {
        CCEmails = append(CCEmails,&emails[i])
    }
    fmt.Println(CCEmails)
    
    for i := range CCEmails {
        fmt.Println(CCEmails[i], *CCEmails[i])
    }

上面的代码遵循指针语义。它在原始数组上循环并将特定元素的地址附加到地址片中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多