值接收者和指針接收者實作接口的差別
使用值接收者實作接口和使用指針接收者實作接口有什麼差別呢?接下來我們通過一個例子看一下其中的差別。
我們有一個
Mover
接口和一個
dog
結構體。
type Mover interface {
move()
}
type dog struct {}
一、 值接收者實作接口
func (d dog) move() {
fmt.Println("狗會動")
}
此時實作接口的是
dog
類型:
func main() {
var x Mover
var wangcai = dog{} // 旺财是dog類型
x = wangcai // x可以接收dog類型
var fugui = &dog{} // 富貴是*dog類型
x = fugui // x可以接收*dog類型
x.move()
}
從上面的代碼中我們可以發現,使用值接收者實作接口之後,不管是dog結構體還是結構體指針dog類型的變量都可以指派給該接口變量。因為Go語言中有對指針類型變量求值的文法糖,dog指針
fugui
内部會自動求值。
二、指針接收者實作接口
func (d *dog) move() {
fmt.Println("狗會動")
}
func main() {
var x Mover
var wangcai = dog{} // 旺财是dog類型
x = wangcai // x不可以接收dog類型
var fugui = &dog{} // 富貴是*dog類型
x = fugui // x可以接收*dog類型
}
type People interface {
Speak(string) string
}
type Student struct{}
func (stu *Student) Speak(think string) (talk string) {
if think == "sb" {
talk = "你是個大帥比"
} else {
talk = "您好"
}
return
}
func main() {
// var peo People = Student{} // 不能通過
var peo People = &Student{} // 能通過 因為實作的接口為指針接收者
think := "bitch"
fmt.Println(peo.Speak(think))
}
三、總結
- 如果采用的是全部都是值接收者,那麼既可以将執行個體化好的結構體對象指派給接口變量,也可以将執行個體化好的結構體對象的指針指派給接口變量
- 如果采用的包含指針接收者,那麼隻能将執行個體化好的結構體對象的指針指派給接口變量
在當下的階段,必将由程式員來主導,甚至比以往更甚。