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这个设计是因为接口值持有的类型必须是动态的。

你可能感兴趣的:(go语言)