2016-03-15 93 views
-1

在旅途中我似乎有兩個選擇:我應該使用指向結構體的指針還是僅在結構體中定義我的funcs?

foo := Thing{} 
foo.bar() 

foo := &Thing{} 
foo.bar() 


func (self Thing) bar() { 
} 

func (self *Thing) bar() { 
} 

有什麼更好的辦法來有自的事物或自定義我的funcs中*的事?

編輯:這是不是方法和功能問題的副本。這個問題與Thing和&事情有關,我認爲這是不同的足以說明它自己的網址。

+2

可能的重複[函數和方法在Go中有什麼區別?](http://stackoverflow.com/questions/8263546/whats-the-difference-of-functions-and-methods-in-go ) – rkmax

+0

[「指針與參數和返回值中的值」](http://stackoverflow.com/questions/23542989/pointers-vs-values-in-parameters-and-return-values/23551970#23551970)談到一些相關的問題。 – twotwotwo

回答

1

沒有明確的答案,但它們完全不同。當您不使用指針時,「按值傳遞」意味着當您使用「通過引用傳遞的指針」時,您調用它的對象將是不可變的(修改副本)。我會說更多的時候你會使用指針變體,但它完全是情境化的,沒有更好的方法。

如果你看一下不同的編程框架/類庫,你會看到那裏的作者都有意選擇通過值或引用做的事情很多例子。例如,在C#.NET中,這是結構和類之間的根本區別,像GuidDateTime這樣的類型被故意實現爲結構體(值類型)。再次,我認爲指針通常是更好的選擇(如果你仔細看看.NET,幾乎所有的東西都是一個類,引用類型),但它絕對取決於你希望通過類型和/或你想要消費者/其他開發人員與之交互。你可能需要考慮性能和併發性(也許你希望所有東西都是有價值的,所以你不必擔心類型上的併發操作,也許你需要一個指針,因爲對象內存佔用很大,複製它會使你的程序太慢或消耗)。

2

看看這個項目從the official FAQ

對於程序員來說不習慣指針, 之間的區別這兩個例子可能會造成混淆,但情況其實 很簡單。在類型上定義方法時,接收者(位於上述示例中的 中)的行爲完全如同它是 方法的參數。是否將接收器定義爲值或作爲指針是 相同的問題,那麼,作爲函數參數應該是 值還是指針。有幾個考慮因素。

首先,也是最重要的,它的方法,需要修改 接收器?如果是這樣,接收器必須是一個指針。 (切片和地圖 充當引用,所以他們的故事是一個小更微妙的,但對於 例如改變的方法中的片段的長度的接收器必須 仍然是一個指針。)在上述的例子中,如果pointerMethod修改 的S的領域,主叫方會看到這些變化,但valueMethod是 稱爲呼叫者的參數的副本(這是傳遞價值的 定義),所以改變它使會無形地調用者。

順便說,指針接收器是相同的在Java中,雖然 在Java指針蓋下隱藏的情況;這是Go的 價值接收器是不尋常的。

二是對效率的考慮。如果接收器很大,例如一個大的結構,使用指針 接收器將會便宜得多。

接下來是一致性。如果某些類型的方法必須具有指針接收器,則其餘部分也應該如此,因此無論使用何種類型,該方法集均爲 。有關詳細信息,請參閱 方法集一節。

對於基本類型,切片和小型結構等類型,接收器的價格非常便宜,因此除非方法的語義需要 指針,否則值接收器是高效且清晰的。