Если последнее возвращаемое значение "должно быть" и error
не используют Implements
, этого недостаточно, x реализует e не совпадает с x is 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() == "")
}
}
This выводит :
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() == "")
}
}
Это выходы :
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() == "")
}
}
Это выводит :
implements error? true
is error? true