天天看點

值接收者和指針接收者實作接口的差別

值接收者和指針接收者實作接口的差別

使用值接收者實作接口和使用指針接收者實作接口有什麼差別呢?接下來我們通過一個例子看一下其中的差別。

我們有一個

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))
}
           

三、總結

  1. 如果采用的是全部都是值接收者,那麼既可以将執行個體化好的結構體對象指派給接口變量,也可以将執行個體化好的結構體對象的指針指派給接口變量
  2. 如果采用的包含指針接收者,那麼隻能将執行個體化好的結構體對象的指針指派給接口變量

在當下的階段,必将由程式員來主導,甚至比以往更甚。