Go 如何检查函数的返回值是否满足错误接口
我想编写一些代码来检查结构的方法,并对它们做出某些断言,例如,它们返回的最后一个结果应该是错误。我尝试了以下示例脚本:Go 如何检查函数的返回值是否满足错误接口,go,reflection,go-reflect,Go,Reflection,Go Reflect,我想编写一些代码来检查结构的方法,并对它们做出某些断言,例如,它们返回的最后一个结果应该是错误。我尝试了以下示例脚本: import ( "context" "reflect" ) type Service struct { name string } func (svc *Service) Handle(ctx context.Context) (string, error) { return svc.name, nil } func main() {
import (
"context"
"reflect"
)
type Service struct {
name string
}
func (svc *Service) Handle(ctx context.Context) (string, error) {
return svc.name, nil
}
func main() {
s := &Service{}
t := reflect.TypeOf(s)
for i := 0; i < t.NumMethod(); i++ {
f := t.Method(i).Func.Type()
f.Out(f.NumOut() - 1).Implements(reflect.TypeOf(error))
}
}
相反,compile的内容是结尾处的以下两行:
var err error
f.Out(f.NumOut() - 1).Implements(reflect.TypeOf(err))
然而,这引起了恐慌:
panic: reflect: nil type passed to Type.Implements
检查最后一个参数是否实现错误接口的正确方法是什么?换句话说,如何获取错误接口的reflect.Type?使用指向接口的指针,并获取其元素,如下所示:
f.Out(f.NumOut() - 1).Implements(reflect.TypeOf((*error)(nil)).Elem())
使用指向接口的指针,并获取其元素,如下所示:
f.Out(f.NumOut() - 1).Implements(reflect.TypeOf((*error)(nil)).Elem())
要在不使用现有错误的情况下获取错误的reflect.TypeOf,可以使用以下一行:
reflect.TypeOf((*error)(nil)).Elem()
基本上,它首先获取指向error*error的指针的类型,然后Elem将TypeOf与错误的类型区分开来
要在不使用现有错误的情况下获取错误的reflect.TypeOf,可以使用以下一行:
reflect.TypeOf((*error)(nil)).Elem()
基本上,它首先获取指向error*error的指针的类型,然后Elem将TypeOf与错误的类型区分开来
如果最后一个返回值应为且错误不使用工具,则这是不够的,x工具e与x工具e不同
只需检查类型的名称和包路径。对于预声明的类型(包括错误),包路径为空字符串
实现错误的非错误类型
名为error的本地声明类型,它未实现内置错误
实际的内置错误
如果最后一个返回值应为且错误不使用工具,则这是不够的,x工具e与x工具e不同
只需检查类型的名称和包路径。对于预声明的类型(包括错误),包路径为空字符串
实现错误的非错误类型
名为error的本地声明类型,它未实现内置错误
实际的内置错误
您可能想要确定最后一个结果是否有类型错误,而不是它实现了错误。如果是,请使用f.outp.NumOut-1==reflect.TypeOf*errornil.Elem.mably duplicate:。您可能希望确定最后一个结果是否存在类型错误,而不是它实现了错误。如果是,请使用f.outp.NumOut-1==reflect.TypeOf*errornil.Elem。可能的重复项:。
implements error? true
is error? false
type Service struct {
name string
}
type error interface { Abc() }
func (svc *Service) Handle(ctx context.Context) (string, error) {
return svc.name, nil
}
type builtin_error interface { Error() string }
func main() {
s := &Service{}
t := reflect.TypeOf(s)
for i := 0; i < t.NumMethod(); i++ {
f := t.Method(i).Func.Type()
rt := f.Out(f.NumOut() - 1)
fmt.Printf("implements error? %t\n", rt.Implements(reflect.TypeOf((*builtin_error)(nil)).Elem()))
fmt.Printf("is error? %t\n", rt.Name() == "error" && rt.PkgPath() == "")
}
}
implements error? false
is error? false
type Service struct {
name string
}
func (svc *Service) Handle(ctx context.Context) (string, error) {
return svc.name, nil
}
func main() {
s := &Service{}
t := reflect.TypeOf(s)
for i := 0; i < t.NumMethod(); i++ {
f := t.Method(i).Func.Type()
rt := f.Out(f.NumOut() - 1)
fmt.Printf("implements error? %t\n", rt.Implements(reflect.TypeOf((*error)(nil)).Elem()))
fmt.Printf("is error? %t\n", rt.Name() == "error" && rt.PkgPath() == "")
}
}
implements error? true
is error? true