arrays - 底层数组如何在 Golang 中的“切片”中表现
问题描述
我对切片中的数组感到很困惑。代码贴在下面。
我了解 test() 从 main() 获取 arr 的副本,并且 test() 中的“附加”没有分配新数组,因为 cap > len。
但是,测试切片 arr[] 和主切片 arr[] 中的底层数组似乎不同,因为它们的地址不同。
另一方面,test() 中的“追加”操作确实修改了 main() 中的底层数组,因为在打印主切片的底层数组时会出现一个新的“1”。此外,test() 能够设置 arr[0] = 10,这在 main() 中可见。
这是怎么发生的?
slice 中数组的地址取自这篇文章。
func test(arr []int) {
arr[0] = 10
fmt.Printf("test slice - %p \n", &arr) //
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&arr))
data := *(*[10]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("test - %p \n", &data)
arr = append(arr, 1)
fmt.Printf("test slice = %p \n", &arr) //
hdr = (*reflect.SliceHeader)(unsafe.Pointer(&arr))
data = *(*[10]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("test = %p \n", &data)
}
func main() {
var arr []int = make([]int, 4, 10)
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&arr))
data := *(*[10]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("main - %p \n", &data)
test(arr)
hdr = (*reflect.SliceHeader)(unsafe.Pointer(&arr))
data = *(*[10]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("main = %p \n", &data)
fmt.Println("main data ", data)
}
输出:
main - 0xc00009e050
test slice - 0xc0000a6000
test - 0xc00009e0a0
test slice = 0xc0000a6000
test = 0xc00009e0a0
main = 0xc00009e050
main data [10 0 0 0 1 0 0 0 0 0]
解决方案
这个操作:
data := *(*[10]int)(unsafe.Pointer(hdr.Data))
[10]int
将数组复制到data
. 这里,data
是一个新数组,而不是切片的后备数组。
推荐阅读
- flutter - 使用 pushReplacement 时等待孙子弹出
- php - Larave 条件聚合得到多个金额的总和
- python - OpenCV - 自适应阈值/有效降噪?
- javascript - JSON输入ajax意外结束
- linux - 安装适用于 Linux 的 Windows 子系统并收到错误 0xc03a001a 和长列表或问号
- xamarin.forms - 如何截取应用截图上传应用商店?
- sql - 带有数组通配符的“不喜欢任何”子句不起作用
- java - 我们可以在 BlueJ IDE 中加载 .fxml 文件吗?
- r - 根据行中的模式添加后缀
- android - 从片段函数更改 TextView 的值