go语言nil 问题?

golang 这段代码 checkError 为什么会触发 panic ?

package main

import (
    "fmt"
)

type Error struct {
    errCode uint8
}

func (e *Error) Error() string {
    switch e.errCode {
    case 1:
        return "file not found"
    case 2:
        return "time out"
    case 3:
        return "permission denied"
    default:
        return "unknown error"
    }
}

func checkError(err error) {
    if err != nil {
        panic(err)
    }
}

func main() {
    var e *Error
    checkError(e)
}

解答:

首先在main函数里的
var e *Error
这里的e是一个Error类型的指针,而指针的自动初始化为nil,在这里e的确是nil没有错,e==nil。

但是当你把e传入进checkError函数时,发生了变化,因为接受的形参是个error接口类型,所以形参err是一个接口值,而一个接口值实际上是包含了实际值和动态类型两个部分的。

err这个接口值大概是这样的(nil,*Error),这里后面的部分*Error表示它的动态类型。

你把err和外面的e做比较时,因为接口类型会断言,所以会相等,err==e。

但是你把err和nil做比较时,nil实际上是(nil,nil)这种,比较结果自然是false err!=nil

你把nil用显示类型转换一下,变成了(nil,*Error)后就和err相同了, err==(*Error)(nil)

总而言之,就是你把一个拥有实际类型的指针传给了接口,那么这个接口值永远不可能是nil。

golang这个设计是因为接口值持有的类型必须是动态的。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值