带错误代码退出?

用错误代码退出程序的惯用方法是什么?

Exit的文档说“程序立即终止; 延迟的函数不会运行。”而 log.Fatal只调用 Exit。对于那些并非十恶不赦的错误,在不运行延迟函数的情况下终止程序似乎是极端的。

我是否应该传递一些表明出现错误的状态,然后在知道可以安全退出的某个点调用 Exit(1),并且已经运行了所有延迟的函数?

73552 次浏览

是的,实际上,操作系统包提供了这个。

package main


import "os"


func main() {
os.Exit(1)
}

Http://golang.org/pkg/os/#exit

编辑: 所以看起来你知道退出。本文概述了 Panic,它允许延迟函数在返回之前运行。结合使用这个退出可能就是您要寻找的。http://blog.golang.org/defer-panic-and-recover

正如 fas 所提到的,您从 OS 包中获得了 func Exit(exitcode int)

但是,如果您需要应用延迟函数,您总是可以像下面这样使用 defer关键字:

Http://play.golang.org/p/u-has88ug4

您执行所有的操作,影响一个错误变量,并在最后,当一切都清理干净后,您可以安全退出。

否则,你也可以利用恐慌/恢复: Http://play.golang.org/p/903e76gnq-

当你有一个错误,你惊慌失措,结束你清理你捕捉(恢复)它。

我在大多数实际的 main软件包中按照这些思路做了一些事情,以便尽快采用 return err公约,并有一个适当的终止:

func main() {
if err := run(); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}


func run() error {
err := something()
if err != nil {
return err
}
// etc
}

在 Python 中,我通常使用一个模式,它被转换为 Go,看起来像这样:

func run() int {
// here goes
// the code


return 1
}


func main() {
os.Exit(run())
}

我认为最清楚的方法是设置 exitCodemain的顶部,然后 defer关闭作为下一步。这使您可以在 main中的任何位置更改 exitCode,并且它的最后一个值将用以下方式退出:

package main


import (
"fmt"
"os"
)


func main() {
exitCode := 0
defer func() { os.Exit(exitCode) }()


// Do whatever, including deferring more functions


defer func() {
fmt.Printf("Do some cleanup\n")
}()


func() {
fmt.Printf("Do some work\n")
}()


// But let's say something went wrong
exitCode = 1


// Do even more work/cleanup if you want


// At the end, os.Exit will be called with the last value of exitCode
}

产出:

Do some work
Do some cleanup


Program exited: status 1.

去游乐场

请注意,这样做的一个重要缺点是,一旦设置了错误代码,就不会立即退出流程。