猿问

为什么交换成员函数不需要使用指针?

我是Golang的新手。当我尝试实现我的第一个优先级队列时,我发现 Push and Pop 函数需要使用成员的指针,但 Swap 不需要。


我知道,如果您在成员函数中使用指针,则意味着您可以更改实例本身而不是其副本。但是,为什么 Swap 可以使用副本而不是指针呢?


type maxHeap []int


func (max maxHeap) Len() int {

    return len(max)

}


func (max maxHeap) Less(a, b int) bool {

    return max[a] > max[b]

}


func (max maxHeap) Swap(a, b int) {

    max[a], max[b] = max[b], max[a]

}


func (max *maxHeap) Push(a interface{}) {

    *max = append(*max, a.(int))

}

func (max *maxHeap) Pop() interface{} {

    x := (*max)[len(*max)-1]

    *max = (*max)[0 : len(*max)-1]

    return x

}


一只名叫tom的猫
浏览 113回答 2
2回答

FFIVE

尝试这个练习:使用指针接收器编写所有函数。在每个函数中,获取顶部指针的当前值,直到需要更改通过指针存储的值为止。因此,和 分别变为:SwapPushfunc (p *maxHeap) Swap(a, b int) {    max := *p    max[a], max[b] = max[b], max[a]}func (p *maxHeap) Push(a interface{}) {    max := *p    *p = append(max, a.(int))}根据需要对其他函数重复上述步骤。现在,返回每个转换后的函数。哪些人为 *p 分配了新值?哪些函数从不分配新值,而只是继续使用 max?当你回答这个问题时,你应该发现自己开悟了。旁注:由于立即转换为,它可能应该采取.同样,应该只是返回。或者,请参阅标准容器/堆包。PushaintintPopint

红颜莎娜

原因在于,在您的情况下,切片确实是一个指针。切片由指向基础内存的指针、该内存的当前长度和总容量组成。这意味着切片实际上是具有以下三个要素的数据结构:[]int内存指针长度能力你可以把它想象成一个type slice struct {     data     unsafe.Pointer     length   int     capacity int}现在,当您调用它时,它将切片作为输入,并返回切片作为输出。append如果输入切片有足够的容量来添加新元素,则将其更改到位(append是一个特殊的内置函数,它不需要切片指针作为输入,无论如何它都会更改切片)。如果输入切片没有添加新项的能力,则会创建一个具有足够容量的新切片,将旧切片复制到其中,然后在最后添加新数据。然后返回此新切片。在您的情况下,您希望更改函数中的堆。该函数可能会返回一个新切片,您必须用它覆盖现有切片。这意味着您需要指向切片的指针,因为您要替换切片结构。Pushappend在 and 函数中,您可以更改切片的内容,而不是切片数据结构本身。您可以使用切片包含的内存指针访问切片中的数据。这意味着这些函数使用切片数据结构的副本,但切片数据结构的原始副本和副本都指向同一基础内存。切片引用的内存是相同的。由于您不在此处调用 append,因此不需要更新切片本身。SwapLess在函数中,您再次更改切片数据结构,因为您更改了其长度字段。这就是为什么您需要一个指向此处切片的指针。Pop
随时随地看视频慕课网APP

相关分类

Go
我要回答