猿问

如何通过反射将函数断言为类型?

我正在用 Go 编写一个 RPC 服务。我不知道如何将结构方法转换为Handler函数。


我尝试了什么:


type TestService struct{}


func (TestService) Foo(a int) error {

    return nil

}


type Handle func(a int) error


func TestHandle(t *testing.T) {

    ts := new(TestService)

    val := reflect.ValueOf(ts)

    // typ := reflect.TypeOf(ts)


    // fmt.Println(val.Method(0).Interface())

    // fmt.Println(val.Method(0).Type().ConvertibleTo(reflect.TypeOf(new(Handle))))


    switch reflect.Indirect(val).Method(0).Interface().(type) {

    case Handle:

        fmt.Println(" okokok " )

    default:

        fmt.Println(reflect.Indirect(val).Method(0).Type())

    }

}

但它失败了。我应该怎么做?


守着一只汪
浏览 103回答 1
1回答

明月笑刀无情

该方法TestService.Foo属于 type func(a int) error,它与 type 不同Handle(Handle具有相同的基础类型,但它是一种新的、不同的类型)。您必须检查此确切类型:case func(a int) error:    fmt.Println(" okokok ")通过此更改,输出将是:=== RUN   TestHandle okokok --- PASS: TestHandle (0.00s)PASS在Go Playground上尝试一下。请注意,您可以对类型断言执行相同的操作,例如:if _, ok := reflect.Indirect(val).Method(0).Interface().(func(a int) error); ok {     fmt.Println(" okokok ") }在Go Playground试试这个。另请注意,如果您确实想使用Handle类型定义,则可以检查函数值是否可分配给类型变量Handle。使用反射,此检查本质上意味着方法的类型是否可分配给Handle.这就是它的样子:th := reflect.TypeOf(Handle(nil))if reflect.Indirect(val).Method(0).Type().AssignableTo(th) {     fmt.Println(" okokok ") }在Go Playground试试这个。获取函数值上面的解决方案只检查给定的方法是否属于给定的函数类型。如果你还需要函数值(这样你就可以调用它),你可以这样做:使用类型切换时(Go Playground):switch hf := reflect.Indirect(val).Method(0).Interface().(type) { case func(a int) error:     fmt.Println(" okokok ", hf(0))default:     fmt.Println(reflect.Indirect(val).Method(0).Type()) }使用类型断言时(Go Playground):if hf, ok := reflect.Indirect(val).Method(0).Interface().(func(a int) error); ok {     fmt.Println(" okokok ", hf(0)) }使用Value.Convert()(去游乐场):m := reflect.Indirect(val).Method(0) th := reflect.TypeOf(Handle(nil))if m.Type().AssignableTo(th) {     var hf Handle = m.Convert(th).Interface().(Handle)     fmt.Println(" okokok ", hf(0)) }
随时随地看视频慕课网APP

相关分类

Go
我要回答