为什么在实现 golang 类型的 sort.Interface 时方法接收器不需要是指针?

我正在阅读sort stdlib 包的文档,示例代码如下所示:


type ByAge []Person


func (a ByAge) Len() int           { return len(a) }

func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }

正如我所了解的,改变类型的函数T需要*T用作其方法接收器。在的情况下Len,Swap以及Less为什么它的工作原理?还是我误解了 usingT与*Tas 方法接收器之间的区别?


ABOUTYOU
浏览 197回答 2
2回答

慕田峪7331174

Go 有三种引用类型:地图片渠道这些类型的每个实例都在内部持有一个指向实际数据的指针。这意味着当您传递这些类型之一的值时,该值会像其他所有值一样被复制,但内部指针仍指向相同的值。快速示例(在游戏中运行):func dumpFirst(s []int) {&nbsp; &nbsp; fmt.Printf("address of slice var: %p, address of element: %p\n", &s, &s[0])}s1 := []int{1, 2, 3}s2 := s1dumpFirst(s1)dumpFirst(s2)将打印如下内容:address of slice var: 0x1052e110, address of element: 0x1052e100address of slice var: 0x1052e120, address of element: 0x1052e100您可以看到:切片变量的地址发生了变化,但该切片中第一个元素的地址保持不变。

阿晨1998

关于这个完全相同的问题,我刚刚有了一个小小的顿悟。正如已经解释过的,类型化切片(不是指向切片的指针)可以实现该sort.Interface接口;部分原因是,即使切片正在被复制,其字段之一是指向数组的指针,因此对该后备数组的任何修改都将反映在原始切片中。但是,通常情况下,这不足以证明裸片成为可接受的接收器。尝试将结构体修改为方法的接收者通常是不正确的,因为任何append()调用都会更改切片副本的长度,而不会修改原始切片的标头。切片修改甚至可能触发新后备阵列的初始化,从而完全断开复制的接收器与原始切片的连接。然而,就排序的本质而言,在这种sort.Sort情况下这不是问题。它执行的唯一数组修改操作是Swap,这意味着数组所需的内存将保持不变,因此切片不会改变大小,因此切片的实际值(起始索引、长度和数组指针)不会发生变化.我相信这对很多人来说都是显而易见的,但我才突然明白,我认为这可能对其他人有用,因为他们想知道为什么用sort裸片很好地演奏。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go