有没有一种方法可以匹配所有接口?

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

Is there a way to match all interfaces?

问题

当一个结构体实现多个接口时,在函数中匹配它们的最简单方法是什么?

根据Go语言的switch工作方式,下面的函数不是一个选项。

func f(i interface{}) {
    switch i.(type) {
    case A:
        fmt.Println("A")
    case B:
        fmt.Println("B")
    }
}

即使i实现了两个接口,f(i)只会输出A。添加fallthrough也无济于事。那么有没有一种方法可以检查多个接口呢?

参考链接

英文:

When a struct implements multiple interfaces what is the simplest way to match all of them in a function?

The way go's switch works the following function is not an option.

func f(i interface{}) {
	switch i.(type) {
	case A:
		fmt.Println("A")
	case B:
		fmt.Println("B")
	}
}

Even if i implements both interfaces f(i) outputs only A. Adding fallthrough won't help either. So is there a way to check for multiple interfaces?

答案1

得分: 6

你可以使用类型断言来检查一个interface变量是否匹配特定的接口,而不是使用switch语句。如果你想检查多个接口,可以使用多个类型断言的序列:

func f(i interface{}) {
	if _, ok := i.(Aer); ok {
		fmt.Println("A")
	}
	if _, ok := i.(Ber); ok {
		fmt.Println("B")
	}
}

(https://play.golang.org/p/6aJxV_j9oqy)

英文:

You can use a type assertion instead of a switch statement to check whether an interface variable matches a specific interface. If you want to check multiple interfaces, you can use a sequence of multiple type assertions:

func f(i interface{}) {
	if _, ok := i.(Aer); ok {
		fmt.Println("A")
	}
	if _, ok := i.(Ber); ok {
		fmt.Println("B")
	}
}

(https://play.golang.org/p/6aJxV_j9oqy)

答案2

得分: 1

在这里,你的目的并不明确;正如Adrian在评论中指出的,这不是你通常在代码中会找到的东西。

你可能会在某种调试系统中找到类似的东西,其中你想要打印关于某个接口类型的变量的信息,以查看它实现了哪些接口。调试器通常可以直接访问内部类型。在Go中,调试器可以在这里使用reflect系统。reflect故意比调试器所需的要弱一些,但对于这种特殊情况,它提供了你可能想要的功能:你可以通过循环遍历不同的接口类型,并在它们上调用reflect.Type.Implements

bcmlis的答案中的类型断言更高效但不太通用:如果你正在构建自己的迷你调试器,你可能想要为一个打印接口值的函数提供一个潜在接口类型的表格。(如果你正在构建一个真正的调试器,你不会希望有任何这么低效的东西,你会想要直接访问类型系统的内部并读取原始表格...)

英文:

It's not at all clear what your purpose is here; as Adrian notes in comments, this isn't something you would normally find in code.

You might find something like this in some sort of debug system, where you want to print information about a variable of some interface type to see what interface(s) it implements. Debuggers generally have direct access to the internal types. In Go specifically, a debugger could use the reflect system here. reflect is deliberately a little bit weaker than debuggers tend to need, but for this particular case, it provides what you might want: you could have a loop that runs through different interface types and invokes reflect.Type.Implements on them.

The type assertion in bcmills' answer is more efficient but less generalizable: if you're doing your own mini-debugger, you might want to provide a table of potential interface types to a function that prints an interface value. (If you were building a real debugger, you would not want anything this inefficient, you'd want to reach directly into the type system's guts and read out the raw tables....)

huangapple
  • 本文由 发表于 2021年8月10日 21:36:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/68727841.html
匿名

发表评论

匿名网友

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

确定