Go开发中nil不等于nil报错如何解决?为什么会出现nil≠nil

笔者在一次开发过程中,发现明明函数返回了nil的error,但是收到后进行判nil是却不为空,导致认为不为空,报错甚至panic,示例代码:

type MyError struct {
    // 对外的状态码
    Code int
}

func (e MyError) Error() string {
    return fmt.Sprint("错误码: e.Code")
}

func Product() *MyError {
    return nil
}

func Check() {
    var err error
    err = Product()
    // 这里result = true
    result := err != nil
    fmt.Println(result)
    // 下面会空指针panic
    if err != nil {
        fmt.Println(err.Error())
    }
}

一、nil不等于nil报错是什么原因

初看起来会让人觉得很诡异,摸不着头脑。

为什么明明返回的是 nil,却被判定为 err ≠ nil 呢?

先了解下error,其本身是一个接口,有一个Error() 函数:

// The error built-in interface type is the conventional interface for
// representing an error condition, with the nil value representing no error.
type error interface {
    Error() string
}

而对于一个变量来说,它有两个要素,一个是类型,一个是

对于接口变量的判断,是要同时判断类型和值均相等。

var inter interface{}
var err error
var myError *MyError
fmt.Println(inter == nil) // 输出: true
fmt.Println(err == nil)   // 输出: true
fmt.Println(err == inter) // 输出: true
fmt.Println(myError == nil) // 输出: true
fmt.Println(err == myError) // 输出: false

而对于Product返回处理的err,由于product指定了返回类型,故其类型为:*error.MyError 值为:nil

Go开发中nil不等于nil报错如何解决?为什么会出现nil≠nil
fmt.Println(reflect.TypeOf(err), reflect.ValueOf(err))

而进行err == nil 的判断时,对于nil本身,由于error类型是接口变量,而其类型不为空(为*error.MyError),所以这2个不相等。

二、nil不等于nil报错解决办法

1.不预先给值

func Check() {
    // 删去这一行var err error
    err := Product()
    result := err != nil
    fmt.Println(result)
    if err != nil {
        fmt.Println(err.Error())
    }
}

2.类型指定为返回类型

func Check() {
    var err *MyError
    err = Product()
    result := err != nil
    fmt.Println(result)
    if err != nil {
        fmt.Println(err.Error())
    }
}

结语

通过对上述问题的深入剖析,我们不仅解决了“nil不等于nil”的报错问题,还进一步理解了Go语言中接口变量的判断机制。这提醒我们在编程时要格外注意变量的类型和值的匹配问题,尤其是在处理接口和指针类型时。

延展阅读:

2024双11大促,如何让智能机器人客服高效生成并管理营销话术?

淘宝资损防控是什么?电商商家如何避免大促优惠叠加计算不当造成资金损失?

商家要不要报名参与京东支付双11补贴?京东支付补贴活动五大利益点有多少优惠?

咨询方案 获取更多方案详情                        
(0)
研发专家-道长生研发专家-道长生
上一篇 2024年10月20日 上午9:40
下一篇 2024年10月22日 下午7:10

相关推荐