切片结构vs指向结构的指针 [英] Slice of structs vs a slice of pointers to structs
问题描述
我不理解以下代码的行为.在创建匹配结构的列表作为结构指针的一部分时,代码始终会打印原始数组的最后一个元素(实际上不是匹配项),它会打印12和12.但是,如果我将匹配更改为[]小部件,而不是[] * Widget,它将显示10和11.
I don't understand the behavior of the following piece of code. In creating a list of matching structs as a slice of struct pointers, the code always prints the last element of original array (which actually wasn't a match)—it prints 12 and 12. However, if I change matches to be []Widget instead of []*Widget, then it will print 10 and 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
添加到数组中.
That's because when you use the pointers you are adding &w
to the array.
请注意, w
实际上是循环中使用的局部变量,因此,这不是您要添加到 matches
数组中的地址.
Note that w
is actually the local variable used in the loop, so that's not the address you want to add to the matches
array.
(即使变量 w
的 value 在循环中发生变化,其地址也保持不变)
(even though the value of the variable w
changes through the loop, its address stays the same)
当循环结束时, w
以最后一个值结束,这就是为什么它两次打印 12
的原因.
When the loop ends, w
ends up with the last value so that's why it prints 12
two times.
您需要添加匹配的元素的地址.
You need to add the address of the element that matched instead.
如果您这样做:
matches = append(matches, &widgets[i])
然后它也可以很好地与指针配合使用.
Then it'd work fine with pointers as well.
改良的Go游乐场供您测试:
Modified Go playground for you to test it:
https://play.golang.org/p/YE-cokyEHu
这篇关于切片结构vs指向结构的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!