为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 返回 nil 不返回 nil

Golang 返回 nil 不返回 nil

Go
qq_遁去的一_1 2023-05-22 15:55:06
我创建了一个自定义错误类型来包装错误,以便在 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}当我调用一个函数并且它没有返回错误时,我应该仍然能够包装错误。预期的行为是如果错误为零,它应该简单地忽略它,不幸的是它恰恰相反。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。Found error <nil>相反,即使错误为零,它也会打印出来。
查看完整描述

4 回答

?
慕仙森

TA贡献1827条经验 获得超7个赞

由于您的Error类型实现了error接口,因此最简单的解决方案是返回一个errorin Wrap():


func Wrap(err error, str string) error {

    if err == nil {

        return nil

    }

    e := &Error{

        ErrString: str + err.Error(),

    }

    return e

}


查看完整回答
反对 回复 2023-05-22
?
慕妹3242003

TA贡献1824条经验 获得超6个赞

输入错误

error 内置接口类型是表示错误条件的常规接口,nil 值表示没有错误。

type error interface {
    Error() string }

类型err的值不是零。它是类型的值。事实上,是interfaceerrornil*main.Errorerr != nil && err.(*Error) == niltrue


例如,

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

}

游乐场:https://play.golang.org/p/nwNRa2sNwj0


输出:


*main.Error <nil> false true

Found error <nil>


*main.Error <nil> false true

No Errors


查看完整回答
反对 回复 2023-05-22
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

将 foo() 返回值更改为 *Error


func foo() error {

    err := bar()

    return Wrap(err, "bar called")

}

或者:


func Wrap(err error, str string) error{

    if err == nil {

        return nil

    }

    e := &Error{

        ErrString: str + err.Error(),

    }

    return e

}


查看完整回答
反对 回复 2023-05-22
?
交互式爱情

TA贡献1712条经验 获得超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")

产生预期的结果。


查看完整回答
反对 回复 2023-05-22
  • 4 回答
  • 0 关注
  • 139 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信