我创建了一个自定义错误类型来包装错误,以便在Golang中更轻松地进行调试。当有打印错误时它可以工作,但是现在引起了恐慌。
type Error struct {
ErrString string
}
func (e *Error) Error() string {
return e.ErrString
}
func Wrap(err error, str string) *Error {
if err == nil {
return nil
}
e := &Error{
ErrString: str + err.Error(),
}
return e
}
当我调用一个函数时,它不会返回错误,我仍然应该能够包装该错误。
预期的行为是,如果错误为nil,则应该将其忽略,不幸的是,情况恰恰相反。
func foo() error {
err := bar()
return Wrap(err, "bar called")
}
func bar() error {
return nil
}
func main() {
err := foo()
if err != nil {
fmt.Printf("Found error %v\n",err)
return
}
fmt.Println("No Errors")
}
我希望它能打印No errors
。相反,即使错误为nil,它也会打印Found error <nil>
。
答案 0 :(得分:3)
if err != nil
正在将err变量与nil error
进行比较,但实际上是nil *Error
将代码更改为
err:=foo()
var nilerror *Error = nil
if err != nilerror {
fmt.Printf("Found error %v\n",err)
return
}
fmt.Println("No Errors")
产生预期的结果。
答案 1 :(得分:2)
错误内置接口类型是用于 表示错误情况,nil值表示否 错误。
type error interface { Error() string }
err
类型interface
的{{1}}的值不是nil。它是类型error
的值nil
。实际上,*main.Error
是err != nil && err.(*Error) == nil
例如,
true
游乐场:https://play.golang.org/p/nwNRa2sNwj0
输出:
package main
import (
"fmt"
)
func error1() {
err := foo()
fmt.Printf("%T %v %v %v\n", err, err, err == nil, err.(*Error) == nil)
if err != nil {
fmt.Printf("Found error %v\n", err)
return
}
fmt.Println("No Errors")
}
func error2() {
err := foo()
fmt.Printf("%T %v %v %v\n", err, err, err == nil, err.(*Error) == nil)
if err != nil && err.(*Error) != nil {
fmt.Printf("Found error %v\n", err)
return
}
fmt.Println("No Errors")
}
type Error struct {
ErrString string
}
func (e *Error) Error() string {
return e.ErrString
}
func Wrap(err error, str string) *Error {
if err == nil {
return nil
}
e := &Error{
ErrString: str + err.Error(),
}
return e
}
func foo() error {
err := bar()
return Wrap(err, "bar called")
}
func bar() error {
return nil
}
func main() {
error1()
fmt.Println()
error2()
}
答案 2 :(得分:0)
由于您的Error
类型实现了error
接口,所以最简单的解决方案是在error
中返回一个Wrap()
:
func Wrap(err error, str string) error {
if err == nil {
return nil
}
e := &Error{
ErrString: str + err.Error(),
}
return e
}