I checked the reflect package documentation, but didn't find anything. What i'm trying to do is find all structs, that implement interface x. Then iterate over all the structs to execute an action y.
-
I doubt that this is possible. From what I know about the implementation about interfaces, that information is not saved at runtime.fuz– fuz2013-03-10 14:14:35 +00:00Commented Mar 10, 2013 at 14:14
2 Answers
Use a type assertion with an interface like this (playground link). I'm assuming you have some struct instances in mind (maybe in an []interface{} as in the example below).
package main
import "fmt"
type Zapper interface {
Zap()
}
type A struct {
}
type B struct {
}
func (b B) Zap() {
fmt.Println("Zap from B")
}
type C struct {
}
func (c C) Zap() {
fmt.Println("Zap from C")
}
func main() {
a := A{}
b := B{}
c := C{}
items := []interface{}{a, b, c}
for _, item := range items {
if zapper, ok := item.(Zapper); ok {
fmt.Println("Found Zapper")
zapper.Zap()
}
}
}
You can also define the interface on the fly and use item.(interface { Zap() }) in the loop instead if it is a one off and you like that style.
Comments
This cannot be done at runtime, but only statically by inspecting the program packages (and all of the imports recursively). Or by statically inspecting the generated .{o,a} files.
However, one may manually build a list of types (not limited to only structs, why?) satisfying an interface:
if _, ok := concreteInstance.(concreteInterface); ok {
// concreteInstance satisfies concreteInterface
}