gpt4 book ai didi

go - 如何检查函数的返回值是否满足错误接口(interface)

转载 作者:行者123 更新时间:2023-12-01 20:23:16 30 4
gpt4 key购买 nike

我想编写一些代码来检查结构的方法并对它们做出某些断言,例如,它们返回的最后一件事应该是 error .我尝试了以下示例脚本:

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))
}
}

然而,这会产生一个
./main.go:23:51: type error is not an expression

编译的是最后的以下两行:
    var err error
f.Out(f.NumOut() - 1).Implements(reflect.TypeOf(err))

但是,这会产生 panic :
panic: reflect: nil type passed to Type.Implements

检查最后一个参数是否实现 error 的正确方法是什么?界面?换句话说,我如何获得 reflect.Typeerror界面?

最佳答案

如果最后一个返回值“应该”和 error不要使用 Implements ,这还不够,x 实现 e 与 x 是 e 不同。

只需检查类型的名称和包路径。对于预先声明的类型,包括 error ,包路径为空字符串。

实现 error 的非错误类型.

type Service struct {
name string
}

type sometype struct {}

func (sometype) Error() string { return "" }

func (svc *Service) Handle(ctx context.Context) (string, sometype) {
return svc.name, sometype{}
}

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() == "")
}
}

这个 outputs :
implements error? true
is error? false

名为 error 的本地声明类型没有实现内置 error .
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() == "")
}
}

这个 outputs :
implements error? false
is error? false

实际内置 error .
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() == "")
}
}

这个 outputs :
implements error? true
is error? true

关于go - 如何检查函数的返回值是否满足错误接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60499801/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com