【问题标题】:How to implement a PHP function `die()` (or `exit()`) in Go?如何在 Go 中实现 PHP 函数 `die()`(或 `exit()`)?
【发布时间】:2023-03-11 04:54:01
【问题描述】:

在 PHP 中,die() 用于停止运行脚本以防止意外行为。在 Go 中,终止句柄函数的惯用方式是什么? panic()return?

【问题讨论】:

    标签: go exit die


    【解决方案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/KjGFZzTrJ7https://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 方法是一个众所周知的实例;它返回一个字节数和一个错误。但是,如果错误无法恢复怎么办?有时程序根本无法继续。

          【讨论】:

            猜你喜欢
            • 2022-09-23
            • 2014-01-03
            • 1970-01-01
            • 1970-01-01
            • 2011-06-01
            • 1970-01-01
            • 2010-12-20
            相关资源
            最近更新 更多