1 回答

TA贡献1801条经验 获得超8个赞
在阅读我的答案的其余部分之前,请查看这个 SO 答案,以获得对切片实际是什么的真正有用的解释。通过打印出实际的切片标题可能更容易理解发生了什么。请参阅以下示例代码(并转到 playground):
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
testSlice()
}
func testSlice() {
slice := make([]int, 0)
slice = append(slice, 1, 2, 3, 4, 5)
fmt.Printf("%+v\n", (*reflect.SliceHeader)(unsafe.Pointer(&slice)))
slice2 := append(slice, 1)
fmt.Printf("%+v\n", (*reflect.SliceHeader)(unsafe.Pointer(&slice2)))
slice3 := append(slice, 2)
fmt.Printf("%+v\n", (*reflect.SliceHeader)(unsafe.Pointer(&slice3)))
for _, i := range slice2 {
print(i)
}
println()
for _, i := range slice3 {
print(i)
}
}
这将打印如下内容:
&{Data:824634441776 Len:5 Cap:6}
&{Data:824634441776 Len:6 Cap:6}
&{Data:824634441776 Len:6 Cap:6}
这表明所有变量slice、slice2和slice3都指向相同的数据(Data这是指向切片第一个元素的指针)但切片标头本身不同。当您执行appends 时,您正在修改所有变量共享的基础切片,并将新的切片标头存储到新变量中。slice2和的切片标头slice3正在查看相同的数据切片,因此当您出现并执行追加时slice3,您将覆盖所有变量共享的基础切片中的第 6 个元素。
- 1 回答
- 0 关注
- 105 浏览
添加回答
举报