如何在 Go 中实现 PHP 函数 `die()`(或 `exit()`)?
Posted
技术标签:
【中文标题】如何在 Go 中实现 PHP 函数 `die()`(或 `exit()`)?【英文标题】:How to implement a PHP function `die()` (or `exit()`) in Go? 【发布时间】:2016-12-01 00:11:00 【问题描述】:在 php 中,die()
用于停止运行脚本以防止意外行为。在 Go 中,终止句柄函数的惯用方式是什么? panic()
或 return
?
【问题讨论】:
【参考方案1】:如果您不想在退出程序后打印堆栈跟踪,可以使用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。
【讨论】:
【参考方案2】:您应该使用os.Exit
。
Exit 导致当前程序以给定的状态码退出。 通常,代码零表示成功,非零表示错误。这 程序立即终止;未运行延迟函数。
package main
import (
"fmt"
"os"
)
func main()
fmt.Println("Start")
os.Exit(1)
fmt.Println("End")
甚至,你可以使用panic
,它也会停止正常执行但在执行停止时抛出错误。
panic 内置函数会停止当前的正常执行 协程。当函数 F 调用 panic 时,F 的正常执行停止 立即地。运行被 F 推迟执行的任何函数 以通常的方式,然后 F 返回到它的调用者。对来电者 G, 然后 F 的调用表现得像一个恐慌的调用,终止 G 的 执行和运行任何延迟函数。这种情况一直持续到所有 正在执行的 goroutine 中的函数以相反的顺序停止。 此时,程序终止,错误条件为 报告,包括参数的值恐慌。这 终止序列称为恐慌,可以由 内置函数recover。
package main
import "fmt"
func main()
fmt.Println("Start")
panic("exit")
fmt.Println("End")
【讨论】:
【参考方案3】:在 Go 中破坏函数的惯用方法是使用 panic()
。这是在运行时停止执行事件的事实上的方式。如果你想恢复恐慌,你可以使用内置的recover()
函数。
恐慌解释:
Panic 是一个内置函数,可以停止普通的控制流 并开始恐慌。当函数 F 调用 panic 时,执行 F 停止,F中的任何延迟函数都正常执行,然后F 返回给它的调用者。
https://blog.golang.org/defer-panic-and-recover
恢复说明:
Recover 是一个内置函数,可以重新控制恐慌 协程。恢复仅在延迟函数中有用。期间 正常执行,recover 调用将返回 nil 并且没有其他 影响。如果当前的 goroutine 出现恐慌,调用 recovery 将 捕获赋予恐慌的值并恢复正常执行。
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")
【讨论】:
【参考方案4】:您可以在 HTTP 处理程序中使用 panic
。服务器将处理它。见Handler。
如果 ServeHTTP 出现紧急情况,服务器(ServeHTTP 的调用者)会假定紧急情况的影响与活动请求隔离。它会恢复恐慌,将堆栈跟踪记录到服务器错误日志中,然后挂断连接。
函数panic
是为程序无法继续的情况保留的。无法只服务一个请求与无法继续工作不同,所以我会记录错误,设置正确的 HTTP 状态并使用return
。见Effective Go。
向调用者报告错误的常用方法是将错误作为额外的返回值返回。规范的 Read 方法是一个众所周知的实例;它返回一个字节数和一个错误。但是,如果错误无法恢复怎么办?有时程序根本无法继续。
【讨论】:
以上是关于如何在 Go 中实现 PHP 函数 `die()`(或 `exit()`)?的主要内容,如果未能解决你的问题,请参考以下文章