2 回答

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

TA貢獻1842條經驗 獲得超13個贊
原因在于,在您的情況下,切片確實是一個指針。切片由指向基礎內存的指針、該內存的當前長度和總容量組成。這意味著切片實際上是具有以下三個要素的數據結構:[]int
內存指針
長度
能力
你可以把它想象成一個
type slice struct { data unsafe.Pointer length int capacity int}
現在,當您調用它時,它將切片作為輸入,并返回切片作為輸出。append
如果輸入切片有足夠的容量來添加新元素,則將其更改到位(append是一個特殊的內置函數,它不需要切片指針作為輸入,無論如何它都會更改切片)。
如果輸入切片沒有添加新項的能力,則會創建一個具有足夠容量的新切片,將舊切片復制到其中,然后在最后添加新數據。然后返回此新切片。
在您的情況下,您希望更改函數中的堆。該函數可能會返回一個新切片,您必須用它覆蓋現有切片。這意味著您需要指向切片的指針,因為您要替換切片結構。Push
append
在 and 函數中,您可以更改切片的內容,而不是切片數據結構本身。您可以使用切片包含的內存指針訪問切片中的數據。這意味著這些函數使用切片數據結構的副本,但切片數據結構的原始副本和副本都指向同一基礎內存。切片引用的內存是相同的。由于您不在此處調用 append,因此不需要更新切片本身。Swap
Less
在函數中,您再次更改切片數據結構,因為您更改了其長度字段。這就是為什么您需要一個指向此處切片的指針。Pop
- 2 回答
- 0 關注
- 141 瀏覽
添加回答
舉報