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

Is there a way I can determine which interfaces a concrete type implements from an arbitrary list of interfaces? I'm aware of a type switch, but I'd like to know all satisfied interfaces.

For example, given:

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...") }

I can manually test each interface as follows:

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

For a Person value, "mover", and "talker" will print. However, I'd rather have a function like this (non-working) one:

func testInterfaces2(entity interface{}, interfaceList type??) {
    for _, inter := range interfaceList {
        val, ok := entity.(inter)
        if ok {
            // do something with val
        }
    }
}

Is there a way I can achieve something like this pseudo function, maybe through the reflect package or some other means?

You could use this to get a slice of interface types.

Then, you can just check whether the Type of your value implements the interface as in 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
", name, interf.Name())
    } else {
        fmt.Printf("%s is NOT a %s
", name, interf.Name())
    }
}

But I think the use of a Type switch is preferable if at all possible

One thing that go doesn't handle exceptionally well is generics. The Prefered way to do this is a type switch:

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

But like val said, the way to get all of the interfaces that are implemented by a type is (a cleaned up version of val's code):

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
", name, interf.Name())
            } else {
                fmt.Printf("%s is NOT a %s
", 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)
}

Here it is in go play: http://play.golang.org/p/6aqMx5CQvY