使用interface与类型诊断机制判断一个类型是否实现了某个方法

Golang中的interface通常用来定义接口,在接口里提供一些方法,其他类型可以实现(implement)这些方法,通过将接口指针指向不同的类型实例实现多态(polymorphism),这是interface常见的应用场景。

Golang语言还提供了类型诊断机制(type assertion),将类型诊断与interface两者相结合就可以用来判断一个类型是否实现了某个方法。

基本思路是:在需要做判断的代码里定义一个私有的interface,在这个interface里定义唯一的一个方法(待判断的那个方法),通过应用类型诊断机制判断是否实现了这个方法。

代码示例

package main

import (
"fmt"
) type Foo struct {
//...
} type BigFoo struct {
// ...
} func (this *BigFoo)Eat() string {
return "eat food!"
} func sample() {
type Fooer interface {
Eat() string
}
Assertor := func(t interface{}) {
// 是否是Fooer接口,间接判断是否实现了Eat方法
if tmp, ok := t.(Fooer); ok {
fmt.Printf("%T:%s\n", t, tmp.Eat()) // 调用方法
} else {
fmt.Printf("%T not implement Eat() method\n", t)
}
} foo := &Foo{}
bigFoo := &BigFoo{} Assertor(foo)
Assertor(bigFoo)
} func main() {
sample()
}

运行上面代码后的输出如下:

*main.Foo not implement Eat() method
*main.BigFoo:eat food!

通过类型诊断机制判断是否是某个interface,间接判断是否实现了待判断的那个方法。

注意事项

如果直接使用:

if tmp, ok := foo.(Fooer); ok {
  //
}

编辑器会出现 “Invalid type assertion: foo.(Fooer) (non-interface type *Foo on left)” 的提示,解决办法是将值转型成 interface{} 然后再运用类型诊断。

var tempFoo interface{} = foo
if tmp, ok := tempFoo.(Fooer); ok {
  //
}

判断是否实现了某个方法还有其他方式,比如使用reflection、查看源代码等。

上一篇:idea常用快捷键大全


下一篇:ARIMA模型--粒子群优化算法(PSO)和遗传算法(GA)