Go學習筆記-結構體中的方法

方法是什麼

  • Go方法是做用在接受者(我的理解成做用對象)上的一個函數,接受者是某種類型的變量,所以方法是一種特殊類型的函數。
  • 接收者能夠是任何類型,不單單是結構體,Go中的基本類型(int,string,bool等)也是能夠,或者說數組的別名類型,甚至能夠是函數類型。可是,接受者不能是一個接口類型,由於接口是一個抽象的定義,方法是一個具體實現。
  • 一個類型加上它的方法等價於面向對象中的一個類。一個重要的區別是:在 Go 中,類型的代碼和綁定在它上面的方法的代碼能夠不放置在一塊兒,它們能夠存在在不一樣的源文件,惟一的要求是:它們必須是同一個包的。
  • 類型 T(或 *T)上的全部方法的集合叫作類型 T(或 *T)的方法集。
  • 由於方法是函數,因此一樣的,不容許方法重載,即對於一個類型只能有一個給定名稱的方法。可是若是基於接收者類型,是有重載的:具備一樣名字的方法能夠在 2 個或多個不一樣的接收者類型上存在,好比在同一個包裏這麼作是容許的
  • 別名類型不能有它原始類型上已經定義過的方法(由於別名類型和原始類型底層是同樣的)。

定義方法的格式

 1 func(recv recevier_type)methodName(parameter_list)(return_value_list){} 數組

  方法名以前,func關鍵字以後的括號中指定接受者(receiver)。函數

  若是recv是接受者(receiver)的實例,Method1是recv的方法名,那麼方法的調用遵循傳統的object.name選擇器符號:recv.Method1()。假如recv是一個指針,Go會自動解引用。spa

 1 package main
 2 
 3 import "fmt"
 4 
 5 type TwoInts struct {
 6     a int
 7     b int
 8 }
 9 func(ti *TwoInts)Add()int{
10     return ti.a + ti.b
11 }
12 
13 func(ti *TwoInts)Plus()(re int){
14     re = ti.a * ti.b
15     return
16 }
17 
18 func(ti *TwoInts)AddOther(param int)(re int){
19     re = ti.a + ti.b +param
20     return
21 }
22 // 結構體上的例子
23 func main(){
24     tt := new(TwoInts)
25     tt.a = 10
26     tt.b = 20
27 
28     fmt.Println(tt.Add())
29     fmt.Println(tt.Plus())
30 
31     ttt := TwoInts{3,5}
32     fmt.Println(ttt.AddOther(7))
33 }
package main

import "fmt"

type IntVetor []int

func (iv IntVetor) Sum(param int) (re int) {
    su := 0
    for _, v := range iv {
        su = su + v
    }
    re = su + param
    return
}
// 非結構體上的例子
func main() {
    tv := IntVetor{3,4,5}
    fmt.Println(tv.Sum(333))
}

  若是想給基本類型添加方法,通常是行不通的,由於基本類型和你添加方法的包不是同一個,會出現編譯錯誤。指針

 方法和函數的區別

  • 方法只能被其接受者調用
  • 接收者是指針時,方法能夠改變接受者的值(或狀態),函數也能作到
  • 接受者和方法必須在同一個包內

方法的接受者是值或者指針的區別

  • 當接受者是一個值的時候,這個值是該類型實例的拷貝
  • 若是想要方法改變接受者的數據,就在接受者的指針類型上定義該方法。不然,就在普通的值類型上定義方法。

 總結:指針方法和值方法均可以在指針或者非指針上被調用。也就是說,方法接收者是指針類型時,指針類型的值也是調用這個方法,反之亦然。code

內嵌類型的方法和繼承

  當一個匿名類型被內嵌在結構體中時,匿名類型的可見方法也一樣被內嵌,這在效果上等同於外層類型繼承了這些方法,將父類型放在子類型中實現(子類型中的方法,能夠直接使用父類型加點子類型方法的方式調用[father.childMethod()])對象

  可是當父類型和子類類型有相同名字的方法怎麼辦呢?父類型的方法會覆蓋子類型的。blog

 1 package main
 2 
 3 import "fmt"
 4 
 5 type Child struct {
 6     a, b int
 7     Father// 【重點】這裏必須是匿名類型才能夠實現繼承的效果,不然不能夠!!!!!!
 8 }
 9 type Father struct {
10     name string
11 }
12 
13 func (fa *Father) GetName() (re string) {
14     re = chi.name
15     return
16 }
17 
18 func main() {
19     c := Child{1, 3, Father{"Kobe"}}
20     fmt.Println(c.GetName())
21 }
相關文章
相關標籤/搜索