从任意接口列表中满足哪些接口?

时间:2013-12-13 15:32:42

标签: interface go

有没有办法可以确定具体类型实现哪些接口 任意接口列表?我知道一个类型开关,但我想知道所有人都满意 接口。

例如,给定:

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
        }
    }
}

有没有办法可以通过反射包或其他方法实现类似伪函数的东西?

2 个答案:

答案 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)
}

这里是游戏:http://play.golang.org/p/6aqMx5CQvY