Error handling 是否退出并在go中显示错误代码?
退出带有错误代码的程序的惯用方法是什么Error handling 是否退出并在go中显示错误代码?,error-handling,go,exit,Error Handling,Go,Exit,退出带有错误代码的程序的惯用方法是什么 Exit的文档说明“程序立即终止;延迟函数不运行。”,而log.Fatal只调用Exit。对于那些不是令人发指的错误,在不运行延迟函数的情况下终止程序似乎是极端的 我是否应该传递一些表示出现错误的状态,然后在我知道可以安全退出的某个点调用Exit(1),所有延迟函数都已运行?是的,实际上。操作系统包提供了这一点 package main import "os" func main() { os.Exit(1) } 编辑:看来你知道退出了。本
Exit
的文档说明“程序立即终止;延迟函数不运行。”,而log.Fatal
只调用Exit
。对于那些不是令人发指的错误,在不运行延迟函数的情况下终止程序似乎是极端的
我是否应该传递一些表示出现错误的状态,然后在我知道可以安全退出的某个点调用
Exit(1)
,所有延迟函数都已运行?是的,实际上。操作系统包提供了这一点
package main
import "os"
func main() {
os.Exit(1)
}
编辑:看来你知道退出了。本文概述了Panic,它可以让延迟函数在返回之前运行。将其与出口结合使用可能是您想要的 如fas所述,您已经从操作系统包中退出了
func(exitcode int)
但是,如果您需要应用延迟功能,则始终可以使用以下defer
关键字:
func run() int {
// here goes
// the code
return 1
}
func main() {
os.Exit(run())
}
您执行了所有操作,影响了一个错误变量,最后,当一切都被清理干净时,您可以安全地退出
否则,您也可以使用紧急/恢复:
当出现错误时,您会惊慌失措,在捕获(恢复)错误的地方结束清理。我在大多数real
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
关闭作为下一步。您可以在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.
去操场
请注意,这样做的一个重要缺点是,您不会在设置错误代码后立即退出流程。如果全局变量状态默认为
clean
,并在非致命错误时设置为dirty
,该怎么办。在退出main()
之前,可以检查该变量。不是很好,但在某些情况下,这可能是最简单的解决方案。(我很高兴评论不能通过投票:))是的,基本上我就是这么做的。我发现它不雅观,因为我必须避免在main中延迟任何内容(因为我仍然调用Exit(1)来设置返回代码,并且不想杀死延迟的fn),所以我将以前的main(只有三行,其中一行是defer)插入到一个函数中。我希望有人能有更好的办法。到目前为止,有一个人回复了os.Exit,当我在帖子中评论我引用了os.Exit文档时,他们的回复被删除了,现在有另一个答案指向os.Exit。我很确定@dan知道这一点。也许我读错了,或者他编辑了,但我认为他在谈论其他东西。我想我理解你在第一种方法中的意思,但这个例子让我有点困惑。为什么要推迟fct1()和fct2()?这意味着它们将以相反的顺序执行!看来你打算还是不愿意?我认为这是最好的解决办法。您可以从run()
方法返回一个错误,并让main()
处理它,而不考虑它是否合适。不考虑这个问题,但在编写更多的Go代码后,我认为(Gustavo Niemeyer的回答)基本上在所有情况下都更清晰、更易于使用。跟踪函数调用比跟踪延迟容易得多。测试此代码的最佳方法是什么?在函数测试中运行二进制文件。