go语言中的接口有一个特性: 类型不需要显式的声明实现了哪一个接口,只要该类型实现了接口的所有方法,就可在实例化的时候直接定义。

https://learnku.com/docs/the-way-to-go/what-is-the-111-interface/3647

类型(比如结构体)实现接口方法集中的方法,每一个方法的实现说明了此方法是如何作用于该类型的:即实现接口,同时方法集也构成了该类型的接口。实现了 Namer 接口类型的变量可以赋值给 ai (接收者值),此时方法表中的指针会指向被实现的接口方法。当然如果另一个类型(也实现了该接口)的变量被赋值给 ai,这二者(译者注:指针和方法实现)也会随之改变。
类型不需要显式声明它实现了某个接口:接口被隐式地实现。多个类型可以实现同一个接口。
实现某个接口的类型(除了实现接口方法外)可以有其他的方法。
一个类型可以实现多个接口。
接口类型可以包含一个实例的引用, 该实例的类型实现了此接口(接口是动态类型)。
即使接口在类型之后才定义,二者处于不同的包中,被单独编译:只要类型实现了接口中的方法,它就实现了此接口。
所有这些特性使得接口具有很大的灵活性。

假如,我们定义了一个接口 Person ,接口定义有 GetName()GetAge() 方法。
然后定义2个类型, StudentTeacher, 代码如下

package main

import "fmt"

type Person interface {
    GetName() string
    GetAge() uint64
}

type Student struct {
    name string
    age uint64
}

type Teacher struct {
    name string
    age uint64
}

接下来,我希望结构体 Student 实现接口 Person ,只需要我们按照 Person 中,定义好 GetName()GetAge() 方法即可。

func (stu *Student) GetName() string{
    return stu.name
}

func (stu *Student) GetAge() uint64 {
    return stu.age
}

这样就完成了接口实现,可以直接使用, 完整代码 :

package main

import "fmt"

type Person interface {
    GetName() string
    GetAge() uint64
}

type Student struct {
    name string
    age uint64
}

type Teacher struct {
    name string
    age uint64
}

func (stu *Student) GetName() string{
    return stu.name
}

func (stu *Student) GetAge() uint64 {
    return stu.age
}

func main() {
    var wuguozhang Person = &Student{
        name: "wuguozhang",
        age: uint64(26),
    }

    fmt.Printf("I'm %s", wuguozhang.GetName())
}

最终会输出 I'm wuguozhang

现在问题来了,假如我肚子疼了,现在这一段程序急需交给小明来救火,我希望结构体 Teacher() 也实现接口 Person 。 但是即使我多次叮嘱小明,小明仍然可能忘记,有什么办法可以从程序上约束呢?

只要一行代码!就可以解决这个问题。

var _ Person = (*Teacher)(nil)

这一行代码的意思,是定义一个 Person 类型的匿名变量,其值为把 nil 通过类型转换,转换为 Teacher 。 现在如果 Teacher 没有定义方法 GetName()GetAge() , 编译将会直接失败,IDE也会给出报错提示。

参考 : https://github.com/geektutu/7days-golang/issues/10