是否可能接收所有实现特定接口的结构体?

huangapple go评论93阅读模式
英文:

Is it possible to receive all structs that implement a certain interface?

问题

我查看了reflect包的文档,但没有找到任何信息。我想要做的是找到所有实现了接口x的结构体,然后遍历所有结构体来执行动作y。

英文:

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.

答案1

得分: 3

使用类型断言与接口,就像这样(playground链接)。我假设你有一些struct实例在脑海中(可能在一个[]interface{}中,就像下面的例子一样)。

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

如果只是一次性的,并且你喜欢这种风格,你也可以即时定义接口,并在循环中使用item.(interface { Zap() })

英文:

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.

答案2

得分: 2

这不能在运行时完成,只能通过检查程序包(以及所有递归导入)静态地完成。或者通过静态地检查生成的.{o,a}文件。

然而,可以手动构建一个类型列表(不仅限于结构体,为什么?),满足一个接口:

if _, ok := concreteInstance.(concreteInterface); ok {
        // concreteInstance满足concreteInterface
}
英文:

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
}

huangapple
  • 本文由 发表于 2013年3月10日 17:56:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/15320963.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定