You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言string切片转*string切片遇迭代变量地址重复问题及解决

Go中string切片转*string切片的常见坑

首先来看你写的这段代码:

values1 := []string{"a", "b", "c"}
var values2 []*string
for _, v := range values1 {
    fmt.Printf("%p | %T\n", v, v)
    values2 = append(values2, &v)
}
fmt.Println(values2)

运行后输出的指针全是同一个地址,这其实是Go语言range循环的一个典型特性导致的——循环变量v是在循环开始前就声明好的单个变量,每次迭代只是把values1里的当前元素值复制给v,而不是每次迭代都创建一个新的v。

所以:

  • v的内存地址从始至终都是同一个,不管迭代多少次,你取的&v都是这个固定地址
  • 每次迭代时v的值会被覆盖成当前元素的内容,最后循环结束时v的值是"c",所以values2里的所有指针都指向这个最终值的地址

你疑惑的"若v不是指针,它的值为何能变化"——其实很简单,v是一个普通的string变量,每次循环只是对它做赋值操作,把当前元素的值复制给它,所以它的值会跟着迭代过程改变,但它自己的内存位置是固定的。

正确的解决方案

你给出的这段代码是完全正确的思路:

values1 := []string{"a", "b", "c"}
var values2 []*string
for i, _ := range values1 {
    values2 = append(values2, &values1[i])
}

这里直接取原切片中对应索引元素的地址&values1[i],每个元素在原切片里都有独立的内存位置,所以values2里的每个指针都会指向不同的元素地址,完美解决了问题。

另外还有一种等价写法,在循环内部创建临时变量来保存当前元素,这样每次迭代都会生成新的变量,地址也不同:

values1 := []string{"a", "b", "c"}
var values2 []*string
for _, v := range values1 {
    temp := v
    values2 = append(values2, &temp)
}

这种写法也能得到正确的结果,原理是每次循环都创建一个新的temp变量,它的地址是唯一的,保存当前元素的值,再把&temp加入切片。

内容的提问来源于stack exchange,提问作者Martin Magakian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:29:56