我正在用 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)) }
- 1 回答
- 0 关注
- 102 浏览
添加回答
举报
0/150
提交
取消