有没有办法可以确定具体类型实现哪些接口 任意接口列表?我知道一个类型开关,但我想知道所有人都满意 接口。
例如,给定:
type Mover interface { Move() }
type Talker interface { Talk() }
type Flyer interface { Fly() }
type Person struct{}
func (a *Person) Move() {fmt.Println("Moving...") }
func (a *Person) Talk() {fmt.Println("Talking...") }
我可以按如下方式手动测试每个界面:
func testInterfaces(entity interface{}) {
_, ok := entity.(Mover)
if ok {
fmt.Println("mover")
}
_, ok := entity.(Talker)
if ok {
fmt.Println("talker")
}
_, ok := entity.(Flyer)
if ok {
fmt.Println("flyer")
}
}
对于Person值,将打印“mover”和“talker”。但是,我宁愿拥有这样的功能(非工作):
func testInterfaces2(entity interface{}, interfaceList type??) {
for _, inter := range interfaceList {
val, ok := entity.(inter)
if ok {
// do something with val
}
}
}
有没有办法可以通过反射包或其他方法实现类似伪函数的东西?
答案 0 :(得分:3)
您可以使用this来获取一些接口类型。
然后,您可以检查值的Type
是否实现了here中的接口:
interfaces := []reflect.Type{reflect.TypeOf((*Mover)(nil)).Elem(),
reflect.TypeOf((*Talker)(nil)).Elem(),
reflect.TypeOf((*Flyer)(nil)).Elem()}
p := &Person{}
t := reflect.TypeOf(p)
name := t.Elem().Name()
for _, interf := range interfaces {
if t.Implements(interf) {
fmt.Printf("%s is a %s\n", name, interf.Name())
} else {
fmt.Printf("%s is NOT a %s\n", name, interf.Name())
}
}
但我认为如果可能的话,最好使用Type开关
答案 1 :(得分:2)
有一件事情并不能很好地处理泛型。首选方法是类型开关:
func testInterfaces2(entity interface{}) {
switch entity.(type) {
case Mover:
fmt.Println("mover")
case Talker:
fmt.Println("talker")
case Flyer:
fmt.Println("flyer")
default:
fmt.Println("something else")
}
}
但是像val说的那样,获取一个类型实现的所有接口的方法是(val的代码的清理版本):
package main
import "fmt"
import "reflect"
type Mover interface { Move() }
type Talker interface { Talk() }
type Flyer interface { Fly() }
type Person struct{}
func (a *Person) Move() {fmt.Println("Moving...") }
func (a *Person) Talk() {fmt.Println("Talking...") }
func testInterfaces(entity interface{}, interfaces []reflect.Type) {
t := reflect.TypeOf(entity)
name := t.Elem().Name()
for _, interf := range interfaces {
if t.Implements(interf) {
fmt.Printf("%s is a %s\n", name, interf.Name())
} else {
fmt.Printf("%s is NOT a %s\n", name, interf.Name())
}
}
}
func main() {
interfaces := []reflect.Type{
reflect.TypeOf((*Mover)(nil)).Elem(),
reflect.TypeOf((*Talker)(nil)).Elem(),
reflect.TypeOf((*Flyer)(nil)).Elem(),
}
p := &Person{}
testInterfaces(p, interfaces)
}