检查方法类型是否与函数类型匹配
Check if a method type matches a function type
给定以下示例,如何检查方法是否匹配函数签名?
package main
import (
"fmt"
"context"
"reflect"
)
// signature to check
type Fn func(context.Context)
type testStruct struct {}
func (*testStruct) DoSomething(context.Context){}
func (*testStruct) DoSomethingElse([]byte){}
func main() {
structType := reflect.TypeOf(&testStruct{})
for i := 0; i < structType.NumMethod(); i++ {
fmt.Println("======================")
method := structType.Method(i)
fmt.Println(method.Name)
fmt.Println(method.Type.String())
// compare method and Fn signature
}
}
1。使用 reflect.Value.Type().ConvertibleTo
注意 reflect.ValueOf
代替了 reflect.TypeOf
package main
import (
"context"
"fmt"
"reflect"
)
type Fn func(context.Context)
type testStruct struct{}
func (*testStruct) DoSomething(context.Context) {}
func (*testStruct) DoSomethingElse([]byte) {}
func (*testStruct) DoSomethingElse2(context.Context) error { return nil }
func main() {
structType := reflect.ValueOf(&testStruct{})
for i := 0; i < structType.NumMethod(); i++ {
fmt.Println("======================")
method := structType.Method(i)
// compare method and Fn
if method.Type().ConvertibleTo(reflect.TypeOf((Fn)(nil))) {
fmt.Println("function of correct type")
}
}
}
https://play.golang.org/p/A9_bpURinad
2。分别检查输入和输出
package main
import (
"context"
"fmt"
"reflect"
)
type Fn func(context.Context)
type testStruct struct{}
func (*testStruct) DoSomething(context.Context) {}
func (*testStruct) DoSomethingElse([]byte) {}
func main() {
structType := reflect.TypeOf(&testStruct{})
rctx := reflect.TypeOf(new(context.Context)).Elem()
for i := 0; i < structType.NumMethod(); i++ {
fmt.Println("======================")
method := structType.Method(i)
fmt.Println(method.Name)
fmt.Println(method.Type.String())
if method.Type.NumIn() != 2 {
fmt.Println("wrong number of inputs, expected 1")
continue
}
if method.Type.In(1) != rctx {
fmt.Println("input of wrong type, expected context.Context")
continue
}
if method.Type.NumOut() != 0 {
fmt.Println("wrong number of outputs, expected 0")
continue
}
fmt.Printf("%v is a function of correct type\n", method.Name)
}
}
给定以下示例,如何检查方法是否匹配函数签名?
package main
import (
"fmt"
"context"
"reflect"
)
// signature to check
type Fn func(context.Context)
type testStruct struct {}
func (*testStruct) DoSomething(context.Context){}
func (*testStruct) DoSomethingElse([]byte){}
func main() {
structType := reflect.TypeOf(&testStruct{})
for i := 0; i < structType.NumMethod(); i++ {
fmt.Println("======================")
method := structType.Method(i)
fmt.Println(method.Name)
fmt.Println(method.Type.String())
// compare method and Fn signature
}
}
1。使用 reflect.Value.Type().ConvertibleTo
注意 reflect.ValueOf
代替了 reflect.TypeOf
package main
import (
"context"
"fmt"
"reflect"
)
type Fn func(context.Context)
type testStruct struct{}
func (*testStruct) DoSomething(context.Context) {}
func (*testStruct) DoSomethingElse([]byte) {}
func (*testStruct) DoSomethingElse2(context.Context) error { return nil }
func main() {
structType := reflect.ValueOf(&testStruct{})
for i := 0; i < structType.NumMethod(); i++ {
fmt.Println("======================")
method := structType.Method(i)
// compare method and Fn
if method.Type().ConvertibleTo(reflect.TypeOf((Fn)(nil))) {
fmt.Println("function of correct type")
}
}
}
https://play.golang.org/p/A9_bpURinad
2。分别检查输入和输出
package main
import (
"context"
"fmt"
"reflect"
)
type Fn func(context.Context)
type testStruct struct{}
func (*testStruct) DoSomething(context.Context) {}
func (*testStruct) DoSomethingElse([]byte) {}
func main() {
structType := reflect.TypeOf(&testStruct{})
rctx := reflect.TypeOf(new(context.Context)).Elem()
for i := 0; i < structType.NumMethod(); i++ {
fmt.Println("======================")
method := structType.Method(i)
fmt.Println(method.Name)
fmt.Println(method.Type.String())
if method.Type.NumIn() != 2 {
fmt.Println("wrong number of inputs, expected 1")
continue
}
if method.Type.In(1) != rctx {
fmt.Println("input of wrong type, expected context.Context")
continue
}
if method.Type.NumOut() != 0 {
fmt.Println("wrong number of outputs, expected 0")
continue
}
fmt.Printf("%v is a function of correct type\n", method.Name)
}
}