我在Go中使用ref
循环迭代一段结构。
在每个循环中,我指向变量的当前项。
我很困惑为什么指针在下一个循环中改变了值。
例如this code:
for range
我希望能够产生:
package main
import "fmt"
type t struct {
val int
}
func main() {
l := []t{{1}, {2}}
var p *t
for _, i := range l {
fmt.Println("begin", p)
p = &i
fmt.Println("end", p)
}
}
但确实如此:
begin <nil>
end &{1}
begin &{1}
end &{2}
作为参考,在我的实际代码中,我在循环期间检查条件,并返回当前项和前一项。所以我试图保存一个指针,以便在下一次迭代中它也可以访问前一个。
答案 0 :(得分:1)
建立Tim's comment,看起来你可以复制每个循环上的值,而不是指针,然后取消引用它。
package main
import "fmt"
type t struct {
val int
}
func main() {
l := []t{{1}, {2}}
var p t
var i t
for _, i = range l {
fmt.Println("begin", &p)
p = i
fmt.Println("end", &p)
}
}
答案 1 :(得分:1)
另一种选择是使用索引获取指向当前项目的指针:
package main
import "fmt"
type t struct {
val int
}
func main() {
l := []t{{1}, {2}}
var p *t
for index, _ := range l {
fmt.Println("begin", p)
p = &l[index]
fmt.Println("end", p)
}
}
答案 2 :(得分:1)
问题是你要获取循环/范围变量的地址而不是切片中项目的地址。但是,你只是为自己做了很多不必要的工作。首先,为什么不使用i, v := range
或更好i, _ :=
然后你可以i-1
来获取上一个项目?其次,即使您希望将其保存在指针中,仍然使用此语法然后分配p = &l[i]
,这样您就可以获得切片中项目的地址,而不是循环/范围变量的地址。
当使用索引显然更好时,人们太急于使用/每个样式构造...如果你想在每次迭代中使用index-1,那么使用索引应该是你的方法。