为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
守着一只汪 2023-05-22 17:41:35
我正在用 Go 编写一个 RPC 服务。我不知道如何将结构方法转换为Handler函数。我尝试了什么:type TestService struct{}func (TestService) Foo(a int) error {    return nil}type Handle func(a int) errorfunc 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())    }}但它失败了。我应该怎么做?
查看完整描述

1 回答

?
明月笑刀无情

TA贡献1828条经验 获得超4个赞

该方法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))
}


查看完整回答
反对 回复 2023-05-22
  • 1 回答
  • 0 关注
  • 102 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信