亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么交換成員函數不需要使用指針?

為什么交換成員函數不需要使用指針?

Go
一只名叫tom的貓 2022-08-15 10:00:37
我是Golang的新手。當我嘗試實現我的第一個優先級隊列時,我發現 Push and Pop 函數需要使用成員的指針,但 Swap 不需要。我知道,如果您在成員函數中使用指針,則意味著您可以更改實例本身而不是其副本。但是,為什么 Swap 可以使用副本而不是指針呢?type maxHeap []intfunc (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}
查看完整描述

2 回答

?
FFIVE

TA貢獻1797條經驗 獲得超6個贊

嘗試這個練習:使用指針接收器編寫所有函數。在每個函數中,獲取頂部指針的當前值,直到需要更改通過指針存儲的值為止。


因此,和 分別變為:SwapPush


func (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


查看完整回答
反對 回復 2022-08-15
?
紅顏莎娜

TA貢獻1842條經驗 獲得超13個贊

原因在于,在您的情況下,切片確實是一個指針。切片由指向基礎內存的指針、該內存的當前長度和總容量組成。這意味著切片實際上是具有以下三個要素的數據結構:[]int

  1. 內存指針

  2. 長度

  3. 能力

你可以把它想象成一個

type slice struct {
    data     unsafe.Pointer
    length   int
    capacity int}

現在,當您調用它時,它將切片作為輸入,并返回切片作為輸出。append

如果輸入切片有足夠的容量來添加新元素,則將其更改到位(append是一個特殊的內置函數,它不需要切片指針作為輸入,無論如何它都會更改切片)。

如果輸入切片沒有添加新項的能力,則會創建一個具有足夠容量的新切片,將舊切片復制到其中,然后在最后添加新數據。然后返回此新切片。

在您的情況下,您希望更改函數中的堆。該函數可能會返回一個新切片,您必須用它覆蓋現有切片。這意味著您需要指向切片的指針,因為您要替換切片結構。Pushappend

在 and 函數中,您可以更改切片的內容,而不是切片數據結構本身。您可以使用切片包含的內存指針訪問切片中的數據。這意味著這些函數使用切片數據結構的副本,但切片數據結構的原始副本和副本都指向同一基礎內存。切片引用的內存是相同的。由于您不在此處調用 append,因此不需要更新切片本身。SwapLess

在函數中,您再次更改切片數據結構,因為您更改了其長度字段。這就是為什么您需要一個指向此處切片的指針。Pop


查看完整回答
反對 回復 2022-08-15
  • 2 回答
  • 0 關注
  • 141 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號