76

退出带有一些错误代码的程序的惯用方式是什么?

的文档Exit说“程序立即终止;延迟函数没有运行。”,然后log.Fatal只调用Exit. 对于不是令人发指的错误的事情,终止程序而不运行延迟函数似乎是极端的。

我是否应该传递一些指示存在错误的状态,然后Exit(1)在我知道我可以安全退出的某个时候调用,并且所有延迟函数都已运行?

4

5 回答 5

97

我在我的大多数实际包中都按照这些思路做一些事情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
}
于 2013-09-23T22:30:05.973 回答
8

在 python 中,我通常使用转换为 go 的模式,如下所示:

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

    return 1
}

func main() {
    os.Exit(run())
}
于 2013-09-24T15:44:53.173 回答
4

我认为最明确的方法是将 设置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

请注意,这样做的一个重要缺点是您不会在设置错误代码后立即退出该过程。

于 2019-01-30T07:47:39.677 回答
3

正如 fas 所提到的,你有func Exit(exitcode int)来自 os 包。

但是,如果您需要应用延迟函数,您始终可以使用如下defer关键字:

http://play.golang.org/p/U-hAS88Ug4

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

否则,您也可以使用恐慌/恢复: http ://play.golang.org/p/903e76GnQ-

当你遇到错误时,你会惊慌失措,在你捕获(恢复)它的地方结束你的清理工作。

于 2013-09-23T17:37:21.070 回答
-1

是的,实际上。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

于 2013-09-23T17:17:23.250 回答