[英]Pointer and slice reference type - receiver
我認為這在我被召喚后會有點明顯,但現在以下不是點擊。
type Stack []interface{}
func (stack *Stack) Push(x interface{}) {
*stack = append(*stack, x)
}
我有一個叫做 Stack 的類型,它是一片空接口。 鑒於它是空的,Push 方法滿足接口。 鑒於切片是引用類型,為什么不能按值傳入“堆棧”接收器? 此外,在上面的例子中,接收者是作為指針傳遞的,為什么內置的 append 需要再次通過指針傳遞?
IE 為什么這不起作用,因為切片是指向底層數組的引用指針?
func (stack Stack) Push(x interface{}) {
stack = append(stack, x)
}
請參閱Go 博客上的這篇文章。 它詳細解釋了正在發生的事情並完全回答您的問題。
從將切片傳遞給函數部分:
即使切片包含一個指針,它本身也是一個值,理解這一點很重要。 在幕后,它是一個包含指針和長度的結構值。 它不是指向結構的指針。
因此,您要么需要一個指針接收器,要么需要將切片作為值返回,如果您想使用append
修改它。
如果您只想修改切片的內容,您可以簡單地按值傳遞切片:
盡管切片頭是按值傳遞的,但頭包含一個指向數組元素的指針,因此原始切片頭和傳遞給函數的頭的副本描述了相同的數組。 因此,當函數返回時,可以通過原始切片變量看到修改后的元素。
使用append
您正在修改切片標頭。 和
因此如果我們想寫一個修改頭的函數,我們必須將它作為結果參數返回
或者:
讓函數修改切片頭的另一種方法是傳遞一個指向它的指針。
您似乎也對指針的使用感到困惑。 請參閱規范:
對於 T 類型的操作數 x,地址操作 &x 生成一個類型為 *T 的指針,指向 x。
和:
對於指針類型 *T 的操作數 x,指針間接 *x 表示 x 指向的類型 T 的變量。
因此,您的示例*stack = append(*stack, x)
並不意味着您將指針傳遞給append
,恰恰相反 - 您正在取消引用指針以傳遞它指向的值。
您遇到的問題是append
返回對新切片的引用。 除非它是一個指針,否則您不能更改函數接收器的值。
我更推薦的是制作一個包裝結構:
type Stack struct{
data []interface{}
size int
}
func (s *Stack) Push(i interface{}){
s.data = append(s.data,i)
s.size++
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.