退出并带有错误代码?

时间:2013-09-23 16:09:57

标签: error-handling go exit

使用某些错误代码退出程序的惯用方法是什么?

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

我是否应该绕过一些表明存在错误的状态,然后在我知道可以安全退出的某个时刻调用Exit(1),所有延迟函数都已运行?

5 个答案:

答案 0 :(得分:49)

我在大多数真正的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
}

答案 1 :(得分:3)

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

但是,如果您需要应用deferred函数,则始终可以使用defer关键字,如下所示:

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

您执行所有操作,影响错误变量,最后,当清理完所有内容后,您可以安全退出。

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

当你遇到错误时,你会发生恐慌,最后清理你捕捉(恢复)它的地方。

答案 2 :(得分:2)

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

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

    return 1
}

func main() {
    os.Exit(run())
}

答案 3 :(得分:0)

我认为最清晰的方法是将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

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

答案 4 :(得分:-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