2013-09-23 24 views
22

Jaki jest idiomatyczny sposób na zamknięcie programu z kodem błędu?Czy wyjść z kodem błędu?

Dokumentacja do wyjścia mówi "Program kończy się natychmiast, funkcje opóźnione nie są uruchamiane.", A log.Fatal po prostu wywołuje polecenie Exit. Dla rzeczy, które nie są haniebnymi błędami, zakończenie programu bez uruchamiania funkcji odroczonych wydaje się ekstremalne.

Czy mam przekazać jakiś stan, który wskazuje, że wystąpił błąd, a następnie wywołać Exit (1) w pewnym momencie, w którym wiem, że mogę bezpiecznie wyjść, z wszystkimi uruchomionymi funkcjami odroczonymi?

+1

Co o konieczności globalnego stanu zmiennej, która jest 'clean' domyślnie ustawiony na' dirty' na niezakończony zgonem błędu. I przed swoimi wyjściami 'main()' możesz sprawdzić tę zmienną. Nie jest to idealnie ładne, ale w niektórych przypadkach może być najłatwiejszym rozwiązaniem. (Cieszę się, że komentarzy nie można przejmować :)) – topskip

+1

Tak, w zasadzie to właśnie skończyłem. Uważam to za nieeleganckie, ponieważ muszę unikać odkładania czegokolwiek w zasadzie (ponieważ wciąż wołam Exit (1), aby ustawić kod powrotu, i nie chcę zabić mojego odroczonego fn), więc utknąłem to, co było moim głównym (który był tylko trzema liniami, z których jeden jest odroczony) do funkcji. Mam nadzieję, że ktoś będzie miał lepszy sposób. Do tej pory jedna osoba odpowiedziała za pomocą os.Exit, a następnie skasowała ich odpowiedź, gdy skomentowałem, że zacytuję os.Exit docs w moim poście, a teraz jest inna odpowiedź, która wskazuje mi na os.Exit. – dan

Odpowiedz

29

zrobić coś wzdłuż tych linii w większości moich prawdziwych main pakietów, tak że konwencja return err zostanie przyjęty jak najszybciej, i ma właściwego zakończenia:

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

Tak, faktycznie. Pakiet os zapewnia to.

package main 

import "os" 

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

http://golang.org/pkg/os/#Exit

Edit: tak wygląda znasz Wyjdź. W tym artykule omówiono opcję Panic, która umożliwia uruchamianie funkcji odroczonych przed powrotem. Używanie tego w połączeniu z wyjściem może być tym, czego szukasz. http://blog.golang.org/defer-panic-and-recover

+2

Jestem prawie pewny, że @dan o tym wie. – topskip

+0

Może błędnie przeczytałem lub zredagowałem, ale myślałem, że mówił o czymś innym. – d1str0

3

Jak wspomniano przez fas, masz func Exit(exitcode int) z pakietu os.

Jednakże, jeśli potrzebujesz funkcji defered być stosowane, zawsze można użyć defer keywork takiego:

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

wykonywać wszystkie swoje działania, wpływają na zmienną o błędzie, a na samym końcu , kiedy wszystko zostanie oczyszczone, możesz bezpiecznie wyjść.

W przeciwnym razie, można również użyć panikę/odzyskania: http://play.golang.org/p/903e76GnQ-

Kiedy masz błąd, paniki, koniec wystarczy porządki gdzie można złapać (odzyskać) go.

+0

Myślę, że rozumiem, co masz na myśli w pierwszym podejściu, ale przykład jest trochę mylący dla mnie. Po co odraczać fct1() i fct2()? Oznacza to, że zostaną wykonane w odwrotnej kolejności!Wygląda na to, że zamierzasz [coś bardziej w tym stylu] (http://play.golang.org/p/02aNIyQ7K-), czy nie? – marczoid

1

W python I często używają wzór, który przekonwertowane aby przejść wygląda następująco:

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

    return 1 
} 

func main() { 
    os.Exit(run()) 
} 
Powiązane problemy