我不理解以下代码的行为。在创建作为结构指针切片的匹配结构列表时,代码始终会打印原始数组的最后一个元素(实际上不是匹配项),它会打印12和12。但是,如果将匹配项更改为[]窗口小部件代替[] * 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) } }
那是因为当您使用指针时,您将添加&w到数组。
&w
请注意,w实际上这是循环中使用的局部变量,因此,这不是您要添加到matches数组中的地址。
w
matches
(即使变量的 值w在循环中发生变化,其 地址也 保持不变)
循环结束时,w以最后一个值结束,这就是为什么它打印12两次的原因。
12
您需要添加匹配的元素的地址。
如果您这样做:
matches = append(matches, &widgets[i])
然后它也可以很好地与指针一起工作。
修改后的Go游乐场供您测试:
https://play.golang.org/p/YE-cokyEHu