英文:
Exit with error code in go?
问题
在程序中以某个错误代码退出的惯用方式是什么?
Exit
的文档中写道:“程序立即终止;延迟函数不会被执行。”而 log.Fatal
只是调用了 Exit
。对于不是严重错误的情况,终止程序而不运行延迟函数似乎过于极端。
我应该传递一些状态来指示发生了错误,然后在我知道可以安全退出且所有延迟函数都已运行的某个点上调用 Exit(1)
吗?
英文:
What's the idiomatic way to exit a program with some error code?
The documentation for Exit
says "The program terminates immediately; deferred functions are not run.", and log.Fatal
just calls Exit
. For things that aren't heinous errors, terminating the program without running deferred functions seems extreme.
Am I supposed to pass around some state that indicate that there's been an error, and then call Exit(1)
at some point where I know that I can exit safely, with all deferred functions having been run?
答案1
得分: 121
我在大多数真实的main
包中都会按照这样的方式进行操作,以便尽早采用return err
的约定,并进行适当的终止:
func main() {
if err := run(); err != nil {
fmt.Fprintf(os.Stderr, "错误:%v\n", err)
os.Exit(1)
}
}
func run() error {
err := something()
if err != nil {
return err
}
// 其他操作
}
这段代码的作用是在main
函数中调用run
函数,并在run
函数返回错误时打印错误信息并退出程序。
英文:
I do something along these lines in most of my real main
packages, so that the return err
convention is adopted as soon as possible, and has a proper termination:
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
}
答案2
得分: 11
在Python中,我通常使用一种模式,转换为Go语言后如下所示:
func run() int {
// 这里是代码
return 1
}
func main() {
os.Exit(run())
}
希望这个翻译对你有帮助!
英文:
In Python I commonly use a pattern, which being converted to Go looks like this:
func run() int {
// here goes
// the code
return 1
}
func main() {
os.Exit(run())
}
答案3
得分: 6
我认为最清晰的方法是在main
函数的开头设置exitCode
,然后在下一步使用defer
关闭。这样你可以在main
函数的任何地方更改exitCode
,并且它的最后一个值将被用于退出:
package main
import (
"fmt"
"os"
)
func main() {
exitCode := 0
defer func() { os.Exit(exitCode) }()
// 做任何事情,包括延迟更多的函数
defer func() {
fmt.Printf("做一些清理工作\n")
}()
func() {
fmt.Printf("做一些工作\n")
}()
// 但是假设出现了错误
exitCode = 1
// 如果需要,可以继续做更多的工作/清理
// 最后,os.Exit将使用exitCode的最后一个值被调用
}
输出:
做一些工作
做一些清理工作
程序退出:状态 1。
请注意,这种方法的一个重要缺点是,一旦设置了错误代码,你不会立即退出进程。
英文:
I think the most clear way to do it is to set the exitCode
at the top of main
, then defer
closing as the next step. That lets you change exitCode
anywhere in main
, and it's last value will be exited with:
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
}
Output:
Do some work
Do some cleanup
Program exited: status 1.
Go Playgroundhttps://play.golang.org/p/AMUR4m_A9Dw
Note that an important disadvantage of this is that you don't exit the process as soon as you set the error code.
答案4
得分: 3
如fas所提到的,你可以使用os包中的func Exit(exitcode int)
函数。
然而,如果你需要延迟执行的函数,你可以使用defer
关键字,像这样:
http://play.golang.org/p/U-hAS88Ug4
你执行所有的操作,影响一个错误变量,在最后,当所有事情都清理完毕时,你可以安全地退出。
另外,你也可以使用panic/recover:
http://play.golang.org/p/903e76GnQ-
当你遇到错误时,你会触发panic,然后在捕获(recover)它的地方进行清理。
英文:
As mentioned by fas, you have func Exit(exitcode int)
from the os package.
However, if you need the defered function to be applied, you always can use the defer
keyword like this:
http://play.golang.org/p/U-hAS88Ug4
You perform all your operation, affect a error variable and at the very end, when everything is cleaned up, you can exit safely.
Otherwise, you could also use panic/recover:
http://play.golang.org/p/903e76GnQ-
When you have an error, you panic, end you cleanup where you catch (recover) it.
答案5
得分: 0
是的,实际上是这样的。os包提供了这个功能。
package main
import "os"
func main() {
os.Exit(1)
}
你可以在这里查看更多关于os.Exit
的信息:http://golang.org/pkg/os/#Exit
编辑:看起来你已经知道了Exit
。这篇文章概述了Panic
,它可以在返回之前运行延迟函数。结合使用Panic
和Exit
可能是你正在寻找的。你可以在这里阅读更多信息:http://blog.golang.org/defer-panic-and-recover
英文:
Yes, actually. The os package provides this.
package main
import "os"
func main() {
os.Exit(1)
}
http://golang.org/pkg/os/#Exit
Edit: so it looks like you know of Exit. This article gives an overview of Panic which will let deferred functions run before returning. Using this in conjunction with an exit may be what you're looking for. http://blog.golang.org/defer-panic-and-recover
答案6
得分: 0
另一种我遵循的好方法是:
if err != nil {
// log.Fatal会打印错误消息,并内部调用System.exit(1)以终止程序
log.Fatal("致命错误消息")
}
英文:
Another good way I follow is:
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")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论