2013-09-23 10 views
22

Was ist der idiomatische Weg, ein Programm mit einem Fehlercode zu beenden?Exit mit Fehlercode in gehen?

Die Dokumentation für Exit sagt "Das Programm wird sofort beendet; verzögerte Funktionen werden nicht ausgeführt.", Und log.Fatal ruft nur Exit auf. Für Dinge, die keine abscheulichen Fehler sind, erscheint das Beenden des Programms ohne laufende Deferred-Funktionen extrem.

Soll ich einen Zustand weitergeben, der anzeigt, dass ein Fehler aufgetreten ist, und dann Exit (1) an einem Punkt aufrufen, an dem ich weiß, dass ich sicher ausfahren kann und alle zurückgestellten Funktionen ausgeführt wurden?

+1

Wie wäre es mit einem globalen Variablenstatus, der standardmäßig 'clean' ist und bei einem nicht-fatalen Fehler auf' dirty' gesetzt wird. Bevor Sie 'main()' beenden, können Sie nach dieser Variablen suchen. Nicht perfekt nett, aber in einigen Fällen könnte es die einfachste Lösung sein. (Ich bin froh, Kommentare können nicht vertagt werden :)) – topskip

+1

Ja, das ist im Grunde, was ich getan habe. Ich finde es unelegant, weil ich es vermeiden muss, etwas in main zu verschieben (weil ich immer noch Exit (1) anrufe, um den Return-Code zu setzen, und nicht meine verzögerte fn), also steckte ich, was mein Haupt war (das waren nur drei Zeilen, von denen eine eine Verschiebung in eine Funktion ist. Ich hoffe, dass jemand einen besseren Weg hat. Bisher hat eine Person mit os.Exit geantwortet und dann ihre Antwort gelöscht, als ich aussprach, dass ich die os.Exit-Dokumente in meinem Post zitiere, und jetzt gibt es eine andere Antwort, die mich auf os.Exit verweist. – dan

Antwort

29

ich etwas in dieser Richtung in den meisten meiner realen main Pakete, so dass die return err Konvention so bald wie möglich angenommen wird, und hat eine ordnungsgemäße Terminierung:

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

Ja, eigentlich. Das os-Paket bietet dies.

package main 

import "os" 

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

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

Edit: so sieht es aus wie Sie Exit wissen. Dieser Artikel gibt einen Überblick über Panic, bei dem zurückgestellte Funktionen vor der Rückgabe ausgeführt werden. Dies kann in Verbindung mit einem Exit nützlich sein. http://blog.golang.org/defer-panic-and-recover

+2

Ich bin mir ziemlich sicher, dass @dan davon weiß. – topskip

+0

Vielleicht habe ich es falsch gelesen oder bearbeitet, aber ich dachte, dass er über etwas anderes sprach. – d1str0

3

Wie von fas erwähnt, haben Sie func Exit(exitcode int) aus dem os-Paket.

Wenn Sie jedoch die defered Funktion angewendet werden müssen, können Sie immer die defer keywork wie folgt verwenden:

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

Sie führen alle Ihre Operation, beeinflussen eine Fehlervariable und am Ende Wenn alles aufgeräumt ist, kannst du gefahrlos gehen.

Andernfalls könnten Sie auch Panik verwenden/wiederherstellen: http://play.golang.org/p/903e76GnQ-

Wenn Sie einen Fehler haben, Panik Sie, Ende Sie Bereinigungs, wo Sie es fangen (wiederherzustellen).

+0

Ich denke, ich verstehe, was Sie im ersten Ansatz meinen, aber das Beispiel ist ein wenig verwirrend für mich. Warum defct fct1() und fct2()? Dies bedeutet, dass sie in umgekehrter Reihenfolge ausgeführt werden!Es sieht so aus, als ob du etwas anderes vorhast (http://play.golang.org/p/02aNIyQ7K-), oder nicht? – marczoid

1

In Python Ich benutze Muster häufig die konvertiert, um zu gehen sieht so aus: