如何在 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()`)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PHP 中实现装饰器?

如何在 PHP 中实现网络爬虫? [关闭]

如何在 PHP 中实现网络爬虫? [关闭]

PHP中实现函数重载

如何在Golang中实现正确的并行性? goroutines是否与Go1.5 +并行?

在 C++11 中实现 boost::barrier