快速报名
首页 / 干货教程 / 干货教程 / 10天光速入门go语言-接口2

10天光速入门go语言-接口2

Go接口的设计和实现是Go整个类型系统的一大特点。接口组合和嵌入、duck typing等实现了优雅的代码复用、解耦、模块化的特性,而且接口是方法动态分派、反射的实现基础(当然更基础的是编译期为运行时提供的类型信息)。

实现接口:指针接受者与值接受者

在接口(一)上的所有示例中,我们都是使用值接受者(Value Receiver)来实现接口的。我们同样可以使用指针接受者(Pointer Receiver)来实现接口。只不过在用指针接受者实现接口时,还有一些细节需要注意。我们通过下面的代码来理解吧。

package main

import "fmt"

type Describer interface { 

    Describe()

}

type Person struct { 

    name string

    age  int

}

func (p Person) Describe() { // 使用值接受者实现 

    fmt.Printf("%s is %d years old\n", p.name, p.age)

}

type Address struct {

    state  string

    country string

}

func (a *Address) Describe() { // 使用指针接受者实现

    fmt.Printf("State %s Country %s", a.state, a.country)

}

func main() { 

    var d1 Describer

    p1 := Person{"Sam", 25}

    d1 = p1

    d1.Describe()

    p2 := Person{"James", 32}

    d1 = &p2

    d1.Describe()

    var d2 Describer

    a := Address{"Washington", "USA"}

    /* 如果下面一行取消注释会导致编译错误:

      cannot use a (type Address) as type Describer

      in assignment: Address does not implement

      Describer (Describe method has pointer

      receiver)

    */

    //d2 = a

    d2 = &a // 这是合法的

    // 因为在第 22 行,Address 类型的指针实现了 Describer 接口

    d2.Describe()

}

在上面程序中的第 13 行,结构体 Person 使用值接受者,实现了 Describer 接口。

我们在讨论方法的时候就已经提到过,使用值接受者声明的方法,既可以用值来调用,也能用指针调用。不管是一个值,还是一个可以解引用的指针,调用这样的方法都是合法的。

p1 的类型是 Person,在第 29 行,p1 赋值给了 d1。由于 Person 实现了接口变量 d1,因此在第 30 行,会打印 Sam is 25 years old。

接下来在第 32 行,d1 又赋值为 &p2,在第 33 行同样打印输出了 James is 32 years old。棒棒哒。

抢先报名    优先占座