Подтвердить что ты не робот

Выйти с кодом ошибки в go?

Какой идиоматический способ выхода из программы с каким-нибудь кодом ошибки?

Документация для Exit гласит: "Программа немедленно завершается; отложенные функции не запускаются.", И log.Fatal просто вызывает Exit. Для вещей, которые не являются отвратительными ошибками, завершение программы без запуска отложенных функций кажется крайним.

Должен ли я обойти какое-либо состояние, которое указывает на то, что произошла ошибка, и затем вызвать Exit(1) в какой-то момент, когда я знаю, что могу безопасно выйти из системы, когда все отложенные функции были запущены?

4b9b3361

Ответ 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
}

Ответ 2

Как указано в fas, у вас есть func Exit(exitcode int) из пакета os.

Тем не менее, если вам нужно defered функцию, которая будет применяться, вы всегда можете использовать defer ключевое слово, как это:

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

Вы выполняете все свои действия, воздействуете на переменную ошибки и в самом конце, когда все вычищено, вы можете безопасно выйти.

В противном случае вы также можете использовать панику /recovery: http://play.golang.org/p/903e76GnQ-

Когда у вас есть ошибка, вы паникуете, завершаете очистку, где вы ее ловите (восстанавливаете).

Ответ 3

В python я обычно использую шаблон, который преобразуется в go, выглядит так:

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

    return 1
}

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

Ответ 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 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

Обратите внимание, что важным недостатком этого является то, что вы не выходите из процесса, как только вы установите код ошибки.

Ответ 5

Да, на самом деле. Пакет 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