Метод 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))
}