将切片成员的地址追加到另一个切片 [duplicate]

Append address of slice members to another slice [duplicate]

提问人:silencej 提问时间:11/14/2023 最后编辑:iczasilencej 更新时间:11/14/2023 访问量:68

问:

我正在使用 awsses-go-skd,我需要转换为 .to []stringToAddresses []*string

但是,我没有做到。以下是解释原因的最小重现代码:

package main
import "fmt"
func main() {
  a := []string{"a", "b", "c"}
  var b []*string
  for _, s := range a {
    b = append(b, &s)
  }
  for _, s := range b {
    fmt.Printf("%s, ", *s)
  }
}

输出为:c、c、c,我期望:a、b、c、

为什么?以及如何解决它?

字符串 Go 指针 切片 Amazon-SES

评论


答:

1赞 icza 11/14/2023 #1

在每次迭代中都会重用一个循环变量。取其地址将是相同的(只有 1 个循环变量),循环之后的指向值将是上次迭代中设置的值。

这是在 Spec: For 语句中:

init 语句声明的变量在每次迭代中都会重用。

[...]迭代变量可以通过“range”子句使用短变量声明()的形式声明。在这种情况下,它们的类型设置为相应迭代值的类型,并且它们的作用域是“for”语句的块;它们在每次迭代中都会重复使用:=

取元素的地址:

var b []*string
for i := range a { 
    b = append(b, &a[i])
}

或者更有效:

b := make([]*string, len(a))
for i := range a {
    b[i] = &a[i]
}

但是有一个帮手可以做到这一点:aws。字符串切片()

StringSlice 将字符串值的切片转换为字符串指针的切片

因此,您可以简单地写:

b := aws.StringSlice(a)

评论

0赞 silencej 11/14/2023
谢谢。但是有没有关于“获取其地址将相同(只有 1 个循环变量)”的文档?因为例如在 C 中,迭代 var 将随着迭代而变化。
0赞 silencej 11/14/2023
我发现这篇文章 medium.com/golangspec/......这很好地解释了为什么我们应该使用而不是.&a[i]&s
1赞 icza 11/14/2023
@silencej 它在规范中,请参阅编辑后的答案。