簡體   English   中英

指針和切片引用類型 - 接收器

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM