我想在运行时测试一个给定的函数,以验证它是否匹配某个签名。这个签名符合一些接口(interface)就足够了,而不是特定的实现。
我似乎无法找到进行此类验证的正确模式。在运行时,函数的类型正在使用实现。
如何将函数的签名与接口(interface)进行比较?
package main
import "fmt"
type myinteface interface{
DoSomething(int) string
}
type myfunc func(myinteface)
type impl struct {}
func (im *impl) DoSomething(int) string{
return "fsdfsd"
}
func do(i interface{}) {
switch v := i.(type) {
case func(myinteface):
fmt.Print("doesn't stop here")
case func(impl):
fmt.Print("this does work")
default:
fmt.Printf("I don't know about type %T!\n", v)
}
}
func test(im impl) {}
func main() {
do(test)
}
现场观看 playground
最佳答案
您可以使用 reflect
手动检查参数类型包裹。下面是 myinteface
的示例。我检查第一个参数 Implements
是否需要所需的接口(interface)。为简洁起见,我假设函数只有一个强制性参数。对于生产,最好在一个循环中检查参数的数量(用 NumIn()
注释掉的字符串)及其所有类型。
func do(i interface{}) {
val := reflect.ValueOf(i)
typ := val.Type()
// numIn := typ.NumIn()
arg0 := typ.In(0)
modelType := reflect.TypeOf((*myinteface)(nil)).Elem()
if arg0.Implements(modelType) {
fmt.Println("OK")
} else {
fmt.Println("not OK")
}
}
此外,请注意接收者类型:值或指针。例如,这里只有 test2
函数参数实现了 myinteface
,但是 test
没有,因为结构体 impl< 上的指针接收器
.
func test(im impl) {}
func test2(im *impl) {}
func main() {
do(test)
do(test2)
}
演示:https://play.golang.org/p/ZDZKZIh2lW
如果您将结构定义更改为值接收者,那么两个函数的参数都会实现它:
type impl struct{}
func (im impl) DoSomething(int) string {
return "fsdfsd"
}
关于go - 类型开关以通过接口(interface)验证功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47521522/