我注意到panic
将interface{}
作为参数,而fmt.Print
和...interface{}
采用panic
。如果...interface{}
同时使用panic
,会不会更方便?
为什么Go作者将func panic(v interface{})
定义为func panic(v ...interface{})
而不是fmt
(就像他们使用{{1}}一样)?
答案 0 :(得分:4)
panic
一开始并没有只提出一个论点
您可以追溯到2010年3月30日的一个参数实现:
commit 01eaf78 gc:添加panic
和recover
(在运行时仍未实现)
主要的语义变化是强制单一参数恐慌。
规范在commit 5bb29fb中得到修正,而commit 00f9f0c说明了在多个参数之前可能会出现多少恐慌:
src/pkg/bufio/bufio.go
b, err := NewWriterSize(wr, defaultBufSize)
if err != nil {
// cannot happen - defaultBufSize is valid size
- panic("bufio: NewWriter: ", err.String())
+ panic(err)
}
在proposal from March 25th, 2010:
之后我们不希望鼓励混淆Java等语言中出现的错误和异常。
相反,该提议对defer的定义和几个运行时函数稍作改动,以提供一种干净的机制来处理真正异常的条件。
在恐慌期间,如果延迟函数调用调用recover,则recover会返回传递给panic的值并停止恐慌。
在任何其他时间,或在延期呼叫调用的内部函数中,recover返回nil 在停止恐慌之后,延期通话可以使用新参数或相同的参数发生恐慌,继续恐慌 或者,延迟调用可能会编辑其外部函数的返回值,可能会返回错误。
在这些不同的场景中,处理一个传递的值似乎比处理可变数量的参数更容易(特别是涉及implement recover
in C时)。
答案 1 :(得分:2)
因为您传递给panic
的值是您想要恐慌的值,可以使用recover
检索。有多个恐慌值并没有多大意义。
package main
import "fmt"
func main() {
defer func() {
if v := recover(); v != nil {
fmt.Println(v.(int))
}
}()
panic(3)
}
使用恢复值的示例:
有关恐慌和恢复的真实示例,请参阅json包 来自Go标准库。它使用set解码JSON编码的数据 递归函数。遇到格式错误的JSON时,解析器 调用panic来将堆栈展开到顶级函数调用,这就是 从恐慌中恢复并返回一个适当的错误值(见 错误' ' unmarshal' decodeState类型的方法 decode.go)。