![](/img/trans.png)
[英]How to specify the type of a function input and output without using assert?
[英]How to assert a func to a type by reflect?
我正在用 Go 編寫一個 RPC 服務。 我不知道如何將 struct 方法轉換為Handler
func。
我試過的:
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())
}
}
但它失敗了。 我該怎么做?
方法TestService.Foo
的類型為func(a int) error
,它與類型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()
( Go Playground ):
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))
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.