可能只是因为我是 Go 新手,但是在结构数组上使用范围语法的行为并不像我期望的那样。我假设数组项被复制到范围索引,但副本不是深层副本......所以下面有点奇怪。这种行为是否记录在某处
package main
import "fmt"
type Inner struct {
x, y int
}
type Attr struct {
a int
inside []Inner
}
var item = []Attr{
{a: 1, inside: []Inner{{2, 3}, {3, 4}}},
{a: 2, inside: []Inner{{3, 4}, {1, 2}}},
}
func main() {
fmt.Println(item)
for _,i := range item {
// A: The following has no impact on item[].a
i.a = 111
// B: But this does ... why?
i.inside[0].x = 111
}
fmt.Println(item)
for j,_ := range item {
item[j].a = 333
item[j].inside[0].x = 333
}
fmt.Println(item)
}
在循环for _, i := range item
中,每个i
都是相应切片元素的副本。假设,你写:
i := item[0]
i.a = 111
这不会更改切片的原始元素,而只会更改其副本。但是在:
i.inside[0].x = 111
inside
是一个切片,即只是一个引用底层数组的薄包装器,在分配时不会复制。因此,使用i.inside
,您可以处理与items[0].inside
相同的切片。
有关切片内部的更多信息。