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

Why does Go panic() take interface{} instead of ...interface{} as argument?

我注意到 panic 接受 interface{} 作为参数,而 fmt.Print 和类似的接受 ...interface{}。如果 panic 也带 ...interface{} 不是更方便吗?

为什么 Go 作者将 panic 定义为 func panic(v interface{}) 而不是 func panic(v ...interface{})(就像他们对 fmt 所做的那样)?

因为您传递给 panic 的值是您想要恐慌的值,可以使用 recover 检索。拥有多个恐慌值并没有多大意义。

package main

import "fmt"

func main() {
    defer func() {
        if v := recover(); v != nil {
            fmt.Println(v.(int))
        }
    }()
    panic(3)
}

使用恢复值的示例:

For a real-world example of panic and recover, see the json package from the Go standard library. It decodes JSON-encoded data with a set of recursive functions. When malformed JSON is encountered, the parser calls panic to unwind the stack to the top-level function call, which recovers from the panic and returns an appropriate error value (see the 'error' and 'unmarshal' methods of the decodeState type in decode.go).

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

panic一开始不只接受一个参数。
您可以将单参数实现追溯到 2010 年 3 月 30 日:
commit 01eaf78 gc: 添加 panicrecover(在运行时仍未实现)

main semantic change is to enforce single argument to panic.

规范已在 commit 5bb29fb, and 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

We don't want to encourage the conflation of errors and exceptions that occur in languages such as Java.

Instead, this proposal uses a slight change to the definition of defer and a couple of runtime functions to provide a clean mechanism for handling truly exceptional conditions.

During panicking, if a deferred function invocation calls recover, recover returns the value passed to panic and stops the panicking.
At any other time, or inside functions called by the deferred call, recover returns nil.
After stopping the panicking, a deferred call can panic with a new argument, or the same one, to continue panicking.
Alternately, the deferred call might edit the return values for its outer function, perhaps returning an error.

在那些不同的场景中,处理一个要传递的值似乎比处理可变数量的参数更容易(尤其是当涉及到 implement recover in C 时)。