在PHP中,die()
用于停止运行脚本以防止意外行为。在Go中,处理句柄功能的惯用方法是什么? panic()
或return
?
你应该使用os.Exit
。
退出导致当前程序以给定的状态代码退出。通常,代码零表示成功,非零表示错误。该计划立即终止;延迟函数不会运行。
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("Start")
os.Exit(1)
fmt.Println("End")
}
甚至,您可以使用panic
,它也会停止正常执行但在执行停止时抛出Error。
恐慌内置函数会停止当前goroutine的正常执行。当功能F调用恐慌时,F的正常执行立即停止。执行被F推迟的任何函数都以通常的方式运行,然后F返回其调用者。对于调用者G,F的调用则表现为对恐慌的调用,终止G的执行并运行任何延迟函数。这将一直持续到执行goroutine中的所有函数都以相反的顺序停止。此时,程序终止并报告错误条件,包括恐慌参数的值。此终止序列称为恐慌,可以通过内置函数recover进行控制。
package main
import "fmt"
func main() {
fmt.Println("Start")
panic("exit")
fmt.Println("End")
}
您可以在HTTP处理程序中使用panic
。服务器将处理它。见Handler。
如果ServeHTTP发生混乱,服务器(ServeHTTP的调用者)假定恐慌的影响与活动请求隔离。它恢复了恐慌,将堆栈跟踪记录到服务器错误日志,并挂断连接。
函数panic
保留用于程序无法继续的情况。无法仅提供一个请求与无法继续工作不同,因此我会记录错误,设置正确的HTTP状态并使用return
。见Effective Go。
向调用者报告错误的常用方法是将错误作为额外返回值返回。规范的Read方法是一个众所周知的例子;它返回一个字节数和一个错误。但如果错误无法恢复怎么办?有时程序根本无法继续。
在Go中打破函数的惯用方法是使用panic()
。这是在运行时停止执行事件的实际方法。如果你想恢复恐慌,可以使用内置的recover()
功能。
恐慌的解释:
恐慌是一种内置功能,可以阻止普通的控制流并开始恐慌。当函数F调用panic时,F的执行停止,F中的任何延迟函数都正常执行,然后F返回其调用者。
https://blog.golang.org/defer-panic-and-recover
恢复说明:
Recover是一个内置函数,可以重新控制恐慌的goroutine。恢复仅在延迟函数内有用。在正常执行期间,对recover的调用将返回nil并且没有其他效果。如果当前goroutine处于恐慌状态,则对恢复的调用将捕获给予恐慌的值并恢复正常执行。
https://blog.golang.org/defer-panic-and-recover
这是一个简单的例子:
package main
import "fmt"
func badCall() {
panic("Bad call happend!")
}
func test() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("Panicking %s\n\r", err)
}
}()
badCall()
fmt.Println("This is never executed!!")
}
func main() {
fmt.Println("Start testing")
test()
fmt.Println("End testing")
}
如果您不想在退出程序后打印堆栈跟踪,则可以使用os.Exit
。您还可以使用os.Exit
设置特定的退出代码。
示例(https://play.golang.org/p/XhDkKMhtpm):
package main
import (
"fmt"
"os"
)
func foo() {
fmt.Println("bim")
os.Exit(1)
fmt.Println("baz")
}
func main() {
foo()
foo()
}
另外请注意,os.Exit
会立即停止程序并且不会运行任何延迟函数,而panic()
会执行。见https://play.golang.org/p/KjGFZzTrJ7和https://play.golang.org/p/Q4iciT35kP。