Golang 中关于接口的一种妙用
go语言中的接口有一个特性: 类型不需要显式的声明实现了哪一个接口,只要该类型实现了接口的所有方法,就可在实例化的时候直接定义。
https://learnku.com/docs/the-way-to-go/what-is-the-111-interface/3647
类型(比如结构体)实现接口方法集中的方法,每一个方法的实现说明了此方法是如何作用于该类型的:即实现接口,同时方法集也构成了该类型的接口。实现了 Namer 接口类型的变量可以赋值给 ai (接收者值),此时方法表中的指针会指向被实现的接口方法。当然如果另一个类型(也实现了该接口)的变量被赋值给 ai,这二者(译者注:指针和方法实现)也会随之改变。
类型不需要显式声明它实现了某个接口:接口被隐式地实现。多个类型可以实现同一个接口。
实现某个接口的类型(除了实现接口方法外)可以有其他的方法。
一个类型可以实现多个接口。
接口类型可以包含一个实例的引用, 该实例的类型实现了此接口(接口是动态类型)。
即使接口在类型之后才定义,二者处于不同的包中,被单独编译:只要类型实现了接口中的方法,它就实现了此接口。
所有这些特性使得接口具有很大的灵活性。
假如,我们定义了一个接口 Person ,接口定义有 GetName() 和 GetAge() 方法。
然后定义2个类型, Student 和 Teacher, 代码如下
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也会给出报错提示。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。