为什么Go panic()接受接口{}而不是... interface {}作为参数?

时间:2015-01-10 20:39:21

标签: go

我注意到panicinterface{}作为参数,而fmt.Print...interface{}采用panic。如果...interface{}同时使用panic,会不会更方便?

为什么Go作者将func panic(v interface{})定义为func panic(v ...interface{})而不是fmt(就像他们使用{{1}}一样)?

2 个答案:

答案 0 :(得分:4)

panic一开始并没有只提出一个论点 您可以追溯到2010年3月30日的一个参数实现:
commit 01eaf78 gc:添加panicrecover(在运行时仍未实现)

  

主要的语义变化是强制单一参数恐慌。

规范在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)。

来源:http://blog.golang.org/defer-panic-and-recover