接口方法值接收者和指針接收者實現的區別

要實現一個接口,必須實現這個接口的所有方法,實現方法的時候可以使用指針接收者實現,也可以使用值接收者實現,這兩者是有區別

package main

import (
	"fmt"
)

type AnimalInterface interface {
	bake(string) error
}

//Dog ...
type Dog struct {
	name string
}

func (dog Dog) bake(w string) error {
	fmt.Printf("%s bake %s \n", dog.name, w)
	return nil
}

type Cat struct {
	name string
}

func (cat *Cat) bake(w string) error {
	fmt.Printf("%s bake %s \n", cat.name, w)
	return nil
}

func main() {

	var dogBig AnimalInterface = Dog{
		name: "大黃",
	}

	dogBig.bake("吳奇隆")

	var dogLittle AnimalInterface = &Dog{
		name: "小黃",
	}

	dogLittle.bake("李易峯")

	// cannot use Cat literal (type Cat) as type AnimalInterface in assignment:Cat does not implement AnimalInterface (bake method has pointer receiver)
	var catHua AnimalInterface = Cat{
		name: "小花",
	}

	catHua.bake("劉亦菲")

	var catBlue AnimalInterface = &Cat{
		name: "小藍",
	}

	catBlue.bake("張園園")

}

var catHua AnimalInterface = Cat{
	name: "小花",
}
在編譯時候會提示錯誤,cannot use Cat literal (type Cat) as type AnimalInterface in assignment:
Cat does not implement AnimalInterface (bake method has pointer receiver)

類的方法以指針接收者實現接口的時候,只有指向這個類的指針才被認爲實現了該接口
Cat沒有實現接口的bake方法, *Cat才實現了接口的bake方法,所以編譯不通過,但是Dog爲什麼可以呢,Dog是實現了接口bake方法,*Dog 自動實現 了接口的bake方法

下面引用<<Go語言實戰筆記的>>總結
現在我們總結下這兩種規則,首先以方法接收者是值還是指針的角度看。

Methods Receivers Values
(t T) T and *T
(t *T) *T

上面的表格可以解讀爲:如果是值接收者,實體類型的值和指針都可以實現對應的接口;如果是指針接收者,那麼只有類型的指針能夠實現對應的接口。

其次我們我們以實體類型是值還是指針的角度看。

Values Methods Receivers
T (t T)
*T (t T) and (t *T)

上面的表格可以解讀爲:類型的值只能實現值接收者的接口;指向類型的指針,既可以實現值接收者的接口,也可以實現指針接收者的接口。

參考

https://qcrao91.gitbook.io/go/interface/zhi-jie-shou-zhe-he-zhi-zhen-jie-shou-zhe-de-qu-bie
https://www.flysnow.org/2017/04/03/go-in-action-go-interface.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章