我不明白以下code的行为。在创建一个匹配结构列表作为结构指针切片时,代码总是打印原始数组的最后一个元素(实际上不匹配) - 打印12和12.但是,如果我将匹配更改为[] Widget而不是[] * Widget,然后它将打印10和11。
为什么会这样?
package main
import (
"fmt"
)
func main() {
type Widget struct {
id int
attrs []string
}
widgets := []Widget{
Widget{
id: 10,
attrs: []string{"blah", "foo"},
},
Widget{
id: 11,
attrs: []string{"foo", "bar"},
},
Widget{
id: 12,
attrs: []string{"xyz"},
},
}
var matches []*Widget
for _, w := range widgets {
for _, a := range w.attrs {
if a == "foo" {
matches = append(matches, &w)
break
}
}
}
for _, m := range matches {
fmt.Println(m.id)
}
}
答案 0 :(得分:5)
那是因为当您使用指针时,您要将&w
添加到数组中。
请注意,w
实际上是循环中使用的局部变量,因此这不是您要添加到matches
数组的地址。
(即使变量w
的值在循环中发生变化,它的地址保持不变)
当循环结束时,w
以最后一个值结束,这就是它打印12
两次的原因。
您需要添加匹配的元素的地址。
如果你这样做:
matches = append(matches, &widgets[i])
然后它也可以用指针工作。
修改Go操场让你测试它: