2016-04-25 66 views
0

我寫了一些奇怪的代碼,但我不知道它爲什麼可行,我可以從中學到什麼。我從另一個結構中創建了一個切片類型。我在切片類型上做了一個函數來修改它自己。爲了做到這一點,我似乎不得不多加註意*。這些指針發生了什麼?

我想了解Go中的指針並希望有一點幫助。下面是一個例子(http://play.golang.org/p/roU3MEeT3q):

var ClientNames = []string {"Client A", "Client B", "ClientC"} 


type InvoiceSummaries []InvoiceSummary 
type InvoiceSummary struct { 
    Client string 
    Amt int 
} 

func (summaries *InvoiceSummaries) BuildFromAbove() { 
    for _, name := range ClientNames { 
     *summaries = append(*summaries, InvoiceSummary{name, 100}) 
    } 
} 

我的問題是:什麼是目的,對於這些*和爲什麼我沒有使用任何&?

+2

注意,這個問題是不是經常看到,因爲大多數用戶類型往往是結構。當您通過選擇器訪問結構域時,該值會自動爲您解除引用。 – JimB

回答

1

這些*中的每一個的目的是什麼?

通過使方法receiver成爲指針,您可以輕鬆地更改對象的屬性。我認爲這是一個好處。下面的這個例子將證明它。

package main 

import "fmt" 

type someStruct struct { 
    someVar int 
} 

func (s someStruct) changeVal1(newVal int) { 
    s.someVar = newVal 
} 

func (s *someStruct) changeVal2(newVal int) { 
    s.someVar = newVal 
} 

func main() { 
    s := someStruct{0} 
    fmt.Println(s) // {0} 

    s.changeVal1(3) 
    fmt.Println(s) // {0} 

    s.changeVal2(4) 
    fmt.Println(s) // {4} 

    (&s).changeVal2(5) 
    fmt.Println(s) // {5} 
} 

和爲什麼我沒有使用任何&?

指針方法的接收者是比較特殊的,它也可以從非指針結構對象中調用。 s.changeVal2(4)(&s).changeVal2(5)都是有效的&會影響someVar的值。

http://play.golang.org/p/sxCnCD2D6d

1

您必須使用指針接收器 - (summaries *InvoiceSummaries) - 因爲否則參數是通過值傳遞的,有一個指針意味着您傳遞的是對該值的引用。如果不是這樣,那麼你根本無法修改集合。

在方法體內部,您使用了*,因爲它是dereferncing運算符並返回地址處的值。 &符號(&)正好相反,它給出了一個值的地址。

+0

啊。我懂了。所以我用*來聲明一個指針和解引用?我認爲,因爲我在接收器中有*,我不必再擔心它了。 – Walt

+0

@Walt JimB在你的問題的評論中解釋。使用結構體時,它會自動處理,因此您不會經常遇到它,但對於內置類型它是必需的。 – evanmcdonnal

1

你的代碼沒有問題,但通常地址切片不使用。切片是一個小結構,地鼠通常很樂意按照價值傳遞。如果一個方法或函數正在創建一個新的片,那麼gopher很樂意再次通過值返回新的片作爲返回值。

當然,按值傳遞片段並不能保證當方法/函數返回時,後備存儲保持不變。所以它不能用作保證片的數據元素沒有變異的方式。