2016-11-13 40 views
-1

考慮以下結構的值之間的差異:Golang - 返回一個指針和初始化方法

type Queue struct { 
    Elements []int 
} 

會是什麼之間的不同:

func NewQueue() Queue { 
    queue := Queue{} 
    return queue 
} 

func NewQueue() *Queue { 
    queue := &Queue{} 
    return queue 
} 

對我來說,似乎實際上是一樣的,(事實上,嘗試一些入隊和出隊的人會得到相同的結果),但我仍然看到兩種用法在野外,所以也許更好。

+0

簡答:您可以返回,但我認爲您通常希望返回您希望人們使用最多的表單。通常,當它是一個像'time.Time'這樣的小型類型時,您會返回一個值,否則返回一個指針。在答案中說更詳細的內容。 – twotwotwo

回答

2

可以返回一個值,然後調用者調用具有指針接收器的方法。但是,如果調用者總是想要使用指針,因爲對象的大或者因爲方法需要對其進行適當的修改,您最好還是返回一個指針。 Pointers vs. values is a common question in Go and there's an answer trying to break down when to use one or the other.

在一片支持Queue類型的特定情況下,這是非常小的,快速複製的價值,如果你希望能夠到各地複製它,讓每個人都看到哪個複製相同的數據被訪問的時候,你將需要使用一個指針,因爲一個切片實際上是一個開始指針,長度和容量的結構,而當你重新制作或增長它時,切片會發生變化。如果這是一個驚喜,那麼在the mechanics of appendslice usage and internals上的Go博客帖子可能是有用的閱讀。

如果您的隊列不是用於共享或傳遞,而是在單個函數中本地使用,您可以提供一個append風格的接口,其中操作返回一個已修改的隊列,但此時可能只需要use slice tricks directly。如果您的隊列同時使用,請認真思考如何使用緩衝通道,這可能不是您想象的那樣,但很多棘手的問題已經爲您解決了)

另外 - 如果Queue確實添加方法的切片,您可以使它type Queue []int

+0

感謝您的詳細回覆。我可能會在接下來的幾天內增加我的隊列,所以我會把它保存爲一個結構體。 –

+0

Oops點擊發送過快。我不明白的事情是:如果我在上面回來的兩種情況有所不同,那麼以後的使用情況怎麼樣呢?也就是說,無論什麼'隊列'我最終初始化,我用它是一樣的,不管它是一個值還是一個指針,這就是爲什麼我想知道這個區別是否值得。 –

+0

用法不一樣; Go隱藏了C++中存在的'.'和' - >'區別,但其他區別仍然存在。例如,在'q:= NewQueue()'之後,要將'q'傳遞給'func f(q * Queue)',如果'q'是一個值而不是'f(&q) q)'如果它是一個指針。同樣,如果你想在全局或類似的地方存儲一個'Queue'或者'* Queue',你就不能在指針和值之間沒有明確的'&'/'*'。 – twotwotwo