退出带有一些错误代码的程序的惯用方式是什么?
的文档Exit
说“程序立即终止;延迟函数没有运行。”,然后log.Fatal
只调用Exit
. 对于不是令人发指的错误的事情,终止程序而不运行延迟函数似乎是极端的。
我是否应该传递一些指示存在错误的状态,然后Exit(1)
在我知道我可以安全退出的某个时候调用,并且所有延迟函数都已运行?
退出带有一些错误代码的程序的惯用方式是什么?
的文档Exit
说“程序立即终止;延迟函数没有运行。”,然后log.Fatal
只调用Exit
. 对于不是令人发指的错误的事情,终止程序而不运行延迟函数似乎是极端的。
我是否应该传递一些指示存在错误的状态,然后Exit(1)
在我知道我可以安全退出的某个时候调用,并且所有延迟函数都已运行?
我在我的大多数实际包中都按照这些思路做一些事情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())
}
我认为最明确的方法是将 设置exitCode
在 的顶部main
,然后defer
作为下一步关闭。这使您可以更改中的exitCode
任何位置main
,并且它的最后一个值将通过以下方式退出:
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.
去游乐场https://play.golang.org/p/AMUR4m_A9Dw
请注意,这样做的一个重要缺点是您不会在设置错误代码后立即退出该过程。
正如 fas 所提到的,你有func Exit(exitcode int)
来自 os 包。
但是,如果您需要应用延迟函数,您始终可以使用如下defer
关键字:
http://play.golang.org/p/U-hAS88Ug4
您执行所有操作,影响错误变量,最后,当一切都清理干净后,您可以安全退出。
否则,您也可以使用恐慌/恢复: http ://play.golang.org/p/903e76GnQ-
当你遇到错误时,你会惊慌失措,在你捕获(恢复)它的地方结束你的清理工作。
是的,实际上。os 包提供了这个。
package main
import "os"
func main() {
os.Exit(1)
}
http://golang.org/pkg/os/#Exit
编辑:所以看起来你知道退出。本文概述了 Panic,它将让延迟函数在返回之前运行。将它与出口结合使用可能是您正在寻找的。http://blog.golang.org/defer-panic-and-recover