我假设切片是通过引用传递的,但这似乎对值有效,但对数组本身无效。例如,如果我有这样的结构:
l := Line{
Points: []Point{
Point{3, 4},
},
}我可以定义一个变量,它会传递一个对结构切片的引用
slice := l.Points然后,如果我修改它,变量引用的原始结构将反映这些修改。
slice[0].X = 1000
fmt.Printf(
"This value %d is the same as this %d",
slice[0].X,
l.Points[0].X,
)这与数组的行为不同,我假设数组是通过值传递的。因此,例如,如果我使用数组定义了前面的代码:
l := Line{
Points: [1]Point{
Point{3, 4},
},
}
arr := l.Points
arr[0].X = 1000
fmt.Println(arr.[0].X != s.Points[0].X) // equals true, original struct is untouched那么,l结构就不会被修改。
现在,如果我想修改切片本身,我显然不能这样做:
slice = append(slice, Point{99, 100})因为这只会重新定义切片变量,从而丢失原始引用。我知道我可以简单地这样做:
l.Points = append(l.Points, Point{99, 100})但是,在某些情况下,使用另一个变量会更方便,而不必键入整个变量。
我试过这个:
*slice = append(*slice, Point{99, 100})但它不起作用,因为我试图取消引用显然不是指针的对象。
我最终尝试了一下:
slice := &l.Points
*slice = append(l.Points, Point{99, 100})它起作用了,但我不确定发生了什么。为什么slice的值没有被覆盖?append在这里是如何工作的?
发布于 2019-12-01 11:33:14
Append返回一个新的切片,它可能会修改初始切片的原始后备数组。原始切片仍将指向原始支持数组,而不是新的支持数组(它可能在内存中的相同位置,也可能不在内存中的相同位置)
例如(playground)
slice := []int{1,2,3}
fmt.Println(len(slice))
// Output: 3
newSlice := append(slice, 4)
fmt.Println(len(newSlice))
// Output: 4
fmt.Println(len(slice))
// Output: 3 虽然片可以被描述为“指向数组的胖指针”,但它不是指针,因此您不能取消对它的引用,这就是为什么会出现错误的原因。
通过创建一个指向切片的指针,并像上面那样使用append,您可以将指针所指向的切片设置为由append返回的“新”切片。
有关更多信息,请查看Go Slice Usage And Internals
https://stackoverflow.com/questions/59122177
复制相似问题