golang類型方法

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。## methods on values or pointersfunc (s *MyStruct) pointerMethod() { } // method on pointerfunc (s MyStruct) valueMethod() { } // method on valuego語言為類型定義方法時有上述兩種方式,初學者很容易陷入迷惑中,這兩種定義方式有什麼區別?該如何選擇? ### 區別首先我們把函數的形式稍微改變一下:func (s *MyStruct) pointerMethod() ⇒ pointerMethod(s *MyStruct)func func (s MyStruct) valueMethod() ⇒ valueMethod(s MyStruct)這樣我們就能夠知道兩者的區別了 mthod on pointer實際上傳入的是類型值的指標,傳入指標的話就不需要拷貝過程而且通過在函數內對類型值的修改是影響外部變數的。method on value 實際上通過函數傳遞的是類型值的拷貝,如果對象比較大的話拷貝會比較耗時,在函數內對拷貝值所做的改變也不會影響到原值了。 ```var p *Mystruct p.pointerMethod() //實際上是 pointerMethod(p)p.valueMethod() // 實際上是 valueMethod(*p)var p Mystruct p.pointerMethod() //實際上是 pointerMethod(&p)p.valueMethod() // 實際上是 valueMethod(p)```###如何選擇1. 如果方法改變調用者的話,那麼就用 method on pointer 2. 類型比較大,複製一份該類型的值耗時,那麼使用 method on pointer3. 如果有的方法必須是 method on pointer 那麼該類型所有的方法都應該是 method on pointer4. 如果是比較小的類型或者 基礎類型, 分區等使用method on value會比較清晰。5. 如果你不知道改用什麼,那麼就用method on pointer## method set討論什麼是method set之前,先來看下這段代碼```package maintype MyStruct struct {}func (s *MyStruct) pointerMethod() {}func (s MyStruct) valueMethod() {}type IMyStruct interface {pointerMethod()valueMethod()}func main() {p := &MyStruct{}v := MyStruct{}var i IMyStructi = p //沒有問題i = v //error //cannot use v (type MyStruct) as type IMyStruct in assignment: // MyStruct does not implement IMyStruct (pointerMethod method has pointer receiver)}``` 為什麼把一個MyStruct值的指標可以賦值給 IMyStruct介面,而一個MyStruct的值賦值給IMyStruct介面就會報錯?我們上一節的代碼剛剛示範過,實值型別取地址就可以調用method on pointer類型的函數了啊。```var p Mystruct p.pointerMethod() //實際上是 pointerMethod(&p)p.valueMethod() // 實際上是 valueMethod(p)```問題的關鍵在於 var p Mystruct 定義的這個變數是addressable的,所以能夠調用method on pointer類型的函數而將該值賦值給一個interface後,interface會拷貝一份該值,拷貝的值不是addressable的,也就不能再調用pointerMethod了除了interface中的值不是addressable的map中的值也是不能addressable的更精確的理解如下,我就不翻譯了>Method Sets: A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other named type T consists of all methods with receiver type T. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T). Any other type has an empty method set. In a method set, each method must have a unique name.<br>> Calls: A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().## 巢狀型別go語言沒有繼承的概念,但是go語言中的一個結構體可以通過匿名嵌套另外一個結構體來獲得該結構體的函數 ```type Human struct {}func (h Human) Age() {}func (h *Human) Name() {}type Student struct {Human } /*Human 的method set為 (Age)*Human 的method set 為(Age Name)Student的method set (Age)Student *的method set 為(Age Name)*/type Student struct {*Human } /*Student的method set (Age Name)Student *的method set 為(Age Name)*///總結如下type C struct { T *S}類型C的Method Set = T的Method Set + *S的Method Set類型*C的Method Set = *T的Method Set + *S的Method Set```參考文獻[FAQ](http://golang.org/doc/faq#methods_on_values_or_pointers)[MethodSets](https://github.com/golang/go/wiki/MethodSets)[關於Go,你可能不注意的7件事(tonybai的文章都很棒)](http://tonybai.com/2015/09/17/7-things-you-may-not-pay-attation-to-in-go/)
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.