2 回答
TA贡献1828条经验 获得超13个赞
Go 有三种引用类型:
地图
片
渠道
这些类型的每个实例都在内部持有一个指向实际数据的指针。这意味着当您传递这些类型之一的值时,该值会像其他所有值一样被复制,但内部指针仍指向相同的值。
快速示例(在游戏中运行):
func dumpFirst(s []int) {
fmt.Printf("address of slice var: %p, address of element: %p\n", &s, &s[0])
}
s1 := []int{1, 2, 3}
s2 := s1
dumpFirst(s1)
dumpFirst(s2)
将打印如下内容:
address of slice var: 0x1052e110, address of element: 0x1052e100
address of slice var: 0x1052e120, address of element: 0x1052e100
您可以看到:切片变量的地址发生了变化,但该切片中第一个元素的地址保持不变。
TA贡献2037条经验 获得超6个赞
关于这个完全相同的问题,我刚刚有了一个小小的顿悟。
正如已经解释过的,类型化切片(不是指向切片的指针)可以实现该sort.Interface
接口;部分原因是,即使切片正在被复制,其字段之一是指向数组的指针,因此对该后备数组的任何修改都将反映在原始切片中。
但是,通常情况下,这不足以证明裸片成为可接受的接收器。尝试将结构体修改为方法的接收者通常是不正确的,因为任何append()
调用都会更改切片副本的长度,而不会修改原始切片的标头。切片修改甚至可能触发新后备阵列的初始化,从而完全断开复制的接收器与原始切片的连接。
然而,就排序的本质而言,在这种sort.Sort
情况下这不是问题。它执行的唯一数组修改操作是Swap
,这意味着数组所需的内存将保持不变,因此切片不会改变大小,因此切片的实际值(起始索引、长度和数组指针)不会发生变化.
我相信这对很多人来说都是显而易见的,但我才突然明白,我认为这可能对其他人有用,因为他们想知道为什么用sort
裸片很好地演奏。
- 2 回答
- 0 关注
- 190 浏览
添加回答
举报