先看C语言中的类似问题:空字符串。
1 |
const char * empty_str0 = "" ; |
2 | * empty_str1 ="\0empty" ; |
3 | * empty_str2 = NULL; |
以上3个字符串并不相等,但是从某种角度看,它们都是对应空的字符串。
- empty_str0 指向一个空的字符串,但是empty_str0本身的值是有效的。
- empty_str1 指向一个非空的字符串,但是字符串的第一个字符是'\0'。
- empty_str2 本身是一个空的指针。
Go的error是一个interface类型,error的nil问题和C语言的字符串类似。
参考官方的error文档说明:
在底层,interface作为两个成员实现:一个类型和一个值。该值被称为接口的动态值, 它是一个任意的具体值,而该接口的类型则为该值的类型。对于 int 值3, 一个接口值示意性地包含(int,3)。
只有在内部值和类型都未设置时(nil,nil),一个接口的值才为 nil。特别是,一个 nil 接口将总是拥有一个 nil 类型。若我们在一个接口值中存储一个int 类型的指针,则内部类型将为int,无论该指针的值是什么:(*int,nil)。 因此,这样的接口值会是非 nil 的,即使在该指针的内部为 nil。
func returnsError() error {
var p *MyError = nil
if bad() { |
4
p = ErrBad
5 | } |
6
return
p
// Will always return a non-nil error.
7 | } |