一、函数实现接口
Go 语言中除了结构体能够实现接口外,函数作为一等公民也可以实现接口。那么结构体实现接口和函数实现接口有什么区别?
结构体实现接口
定义一个接口 Fighter 以及一个结构体 Hero,Hero 实现 Fighter 接口的 Fight 方法时,方法的接收者为结构体指针。
package main import "fmt" func main(){ // 声明接口变量 var fighter Fighter // 函数接收者是一个指针 hero := Hero{"Peter"} heroPtr:= &hero // Hero 实现 Fighter 接口时函数接收者为结构体指针类型,所有只能将 // 结构体指针赋值给 fighter 接口变量 fighter = heroPtr fighter.Fight("Suit") } type Fighter interface { Fight(interface{}) } type Hero struct { Name string } // 结构体实现接口 func (h *Hero) Fight(interface{}) { fmt.Println(h.Name + " is Fighting!") } 复制代码
执行上述代码,输出结果如下:
Peter is Fighting! 复制代码
函数实现接口
函数的声明不能直接实现接口,需要将函数定义为类型后,使用类型实现结构体。当类型方法被调用时,还需要调用函数本体。
package main import "fmt" func main(){ // 声明接口变量 var fighter Fighter // 实例化一个函数类型对象 funcFighterInstance := FuncFighter(func(v interface{}) { fmt.Println(v, "is Fighting") }) // 赋值给接口变量 fighter = funcFighterInstance fighter.Fight("Peter") } type Fighter interface { Fight(interface{}) } // 定义一个函数类型 type FuncFighter func(interface{}) // 实现 Fighter 接口的 Fight 方法 func ( funcFighter FuncFighter) Fight(i interface{}) { // 调用函数本体,在实例化函数对象时实现函数具体功能,或者直接再次实现函数具体功能,但是实例化函数时定义的函数实现功能会被覆盖。 // 建议直接在这里调用函数本体,在实例化对象时再实现函数的具体功能。 funcFighter(i) } 复制代码
执行上述代码,输出结果如下:
Peter is Fighting 复制代码
当类型方法被调用时可以直接实现函数的内容不用调用函数本体,如果调用函数本体,那就需要在实例化函数类型对象时实现函数的具体内容。
函数与结构体实现的区别就在于结构体可以直接实现接口,而函数实现接口则需要使用 type
关键字定义一个函数类型,在通过该函数类型实现接口,并将该函数类型的实例化对象赋值给接口变量,这样就可以通过接口变量来调用函数类型实现的接口功能。