如何以惯用方式退出具有某些错误代码的程序?
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
}
_
来忽略 fmt.Fprintf(…)
返回的错误。 - emlai我在Python中常用一种模式,在转换为Go语言时,它看起来像这样:
func run() int {
// here goes
// the code
return 1
}
func main() {
os.Exit(run())
}
run()
方法返回一个错误,并让main()
方法自行处理。 - Loupax我认为最清晰的方法是在main
函数的顶部设置exitCode
,然后将关闭操作作为下一步使用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.
Go Playgroundhttps://play.golang.org/p/AMUR4m_A9Dw
请注意,这种方法的一个重要缺点是在设置错误代码后,您不能立即退出进程。
func Exit(exitcode int)
。defer
关键字:
http://play.golang.org/p/U-hAS88Ug4
你执行所有操作,影响一个错误变量,在一切都被清理干净时,你可以安全地退出。是的,实际上可以。os包提供了这个功能。
package main
import "os"
func main() {
os.Exit(1)
}
http://golang.org/pkg/os/#Exit
编辑:看起来你知道Exit。这篇文章概述了Panic,它可以让延迟函数在返回之前运行。将其与Exit结合使用可能是你正在寻找的。http://blog.golang.org/defer-panic-and-recover
我遵循的另一种好方法是:
if err != nil {
// log.Fatal will print the error message and will internally call System.exit(1) so the program will terminate
log.Fatal("fatal error message")
}
main()
退出之前,你可以检查该变量。这并不是完美的解决方案,但在某些情况下可能是最简单的解决方案。(我很高兴评论不能被踩:)) - topskip