将所有项目从切片(src)复制到新切片(dst)后,dst中的所有项目都指向src的最后一项.
package main
import (
"fmt"
)
func main() {
src := []string{"a", "b", "c"}
dst := []*string{}
for _, val := range src {
dst = append(dst, &val)
}
for i, s := range dst {
fmt.Printf("%v - %v\n", i, *s)
}
}
>>> 0 - c
>>> 1 - c
>>> 2 - c
Run Code Online (Sandbox Code Playgroud)
为什么不将"a"和"b"复制到dst切片中?
解决方案很简单,但在对range语句的期望方面具有反直觉性.
变量val只被实例化一次,并保持价值的src[i]每一个迭代.它没有实际的指针src[i].而是将值src[i]复制到分配给的内存中val.通过获取指针,val你得到的就是那个,而不是指针src[i].
package main
import (
"fmt"
)
func main() {
src := []string{"a", "b", "c"}
dst := []*string{}
for _, val := range src {
dst = append(dst, &val)
}
for i, s := range dst {
fmt.Printf("%v - %v - %p\n", i, *s, s)
}
//modify only contents of first index
*dst[0] = "hi val"
for i, s := range dst {
fmt.Printf("%v - %v - %p\n", i, *s, s)
}
}
>>>>
0 - c - 0x1040a120
1 - c - 0x1040a120
2 - c - 0x1040a120
0 - hi val - 0x1040a120
1 - hi val - 0x1040a120
2 - hi val - 0x1040a120
Run Code Online (Sandbox Code Playgroud)
虽然事后证明这很明显 - for _, val- >:= < - range src- 如果你不知道它,它可以咬你的屁股,所以这个警告.
PS.这也适用于src地图.
添加到@RickyA 的答案。
要实现您想要做的事情,您需要执行以下操作:
for i := range src {
dst[i] = &src[i]
}
Run Code Online (Sandbox Code Playgroud)