1. 程式人生 > 實用技巧 >go tour --方法值接收器和指標接收器區別

go tour --方法值接收器和指標接收器區別

有兩個理由使用指標接收器

  1. 第一個是為了讓方法可以修改它的接收器指向的值。
  2. 第二種方法是避免在每次方法呼叫時複製值。例如,如果接收方是一個大的結構體,這可能會更有效率。

通常,給定型別上的所有方法都應該具有值或指標接收器,但不能兩者混合。(我們將在接下來的幾頁中看到原因。)

介面

介面是定義的一組方法簽名。
實現介面必須啊實現介面的所有方法。
實現介面必須要值接收器方法。
在底層,一個介面值可以被認為是一個值和具體型別的元組

(value, type)

呼叫介面值上的方法將在其底層型別上執行同名方法。
如果介面內部的具體值本身是nil,該方法將用nil接收器呼叫。(但還是會呼叫方法,因為有型別,可以在方法內通過判斷接收器為nil 來避免空指標錯誤)

package main

import "fmt"

type I interface {
	M()
}

type T struct {
	S string
}

func (t *T) M() {
	if t == nil {
		fmt.Println("<nil>")
		return
	}
	fmt.Println(t.S)
}

func main() {
	var i I

	var t *T
	i = t
	describe(i)
	i.M()

	i = &T{"hello"}
	describe(i)
	i.M()
}

func describe(i I) {
	fmt.Printf("(%v, %T)\n", i, i)
}

注意,持有nil具體值的介面值本身是非nil的。
nil介面值既不包含值也不包含具體型別。
在nil介面上呼叫方法是一個執行時錯誤,因為在介面元組中沒有型別來指示要呼叫哪個具體方法。

package main

import "fmt"

type I interface {
	M()
}

func main() {
	var i I
	describe(i)
	i.M()
}

func describe(i I) {
	fmt.Printf("(%v, %T)\n", i, i)
}
(<nil>, <nil>)
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x49c106]

goroutine 1 [running]:
main.main()