簡體   English   中英

如何通過反射將 func 斷言為類型?

[英]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 ,它與類型HandleHandle具有相同的底層類型,但它是一個新的、不同的類型)。

你必須檢查這個確切的類型:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM