[Go] panic(nil) 会怎么样?
在Go语言里面,经常会使用panic + recover
的组合来模拟其它语言中的异常处理。像下面这样的写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
上面的代码将会打印出:EOF
。
有一点值得思考的是,我们通过exception != nil
的方式来判断是否发生了异常是否合理?
因为,实际上panic
是允许参数为nil
的。如果为panic(nil)
,会发生什么?
答案是:recover
成功捕获异常,但是我们却没有对它作任何处理。
因为:recover
在返回nil
的时候无法区别是没有抛出异常还是抛出了一个nil
异常。
recover
的官方说明文档如下(注意加粗的那句话):
The recover built-in function allows a program to manage behavior of a panicking goroutine. Executing a call to recover inside a deferred function (but not any function called by it) stops the panicking sequence by restoring normal execution and retrieves the error value passed to the call of panic. If recover is called outside the deferred function it will not stop a panicking sequence. In this case, or when the goroutine is not panicking, or if the argument supplied to panic was nil, recover returns nil. Thus the return value from recover reports whether the goroutine is panicking.
这样一来,语言是乎出现了歧义。
GitHub上也同样出现了这样的提议,建议区别对待这两种返回值,详见:proposal: promote panic(nil) to non-nil panic value。
大家各抒己见,比如有人提议像下面这样:
1 2 3 |
|
也就是允许recover
也可以像someMap[key]
这样允许返回一个值或两个值。这样同样兼容以前的代码。是一个很不错的提议。但是,从回帖看,官方好像不是很喜欢这样做。不然早就已经提上日程了。