Heim  >  Artikel  >  Backend-Entwicklung  >  Nehmen Sie eine kleine Falle von Golang Recover auf

Nehmen Sie eine kleine Falle von Golang Recover auf

藏色散人
藏色散人nach vorne
2020-12-22 15:56:503600Durchsuche

Ich hoffe, es wird den Freunden helfen, die es brauchen!

Nehmen Sie eine kleine Falle von Golang Recover auf

1.error

Golang wird oft dafür kritisiert, dass es keinen leistungsstarken und praktischen Ausnahmebehandlungsmechanismus gibt, wie Java, PHP, Python usw., über einen Try-Catch Dieser Mechanismus zum Abfangen von Ausnahmen kann sehr praktisch sein, um verschiedene unerwartete Situationen zu bewältigen, die während des Programmbetriebs auftreten können. Genau genommen handelt es sich bei Fehlern und Ausnahmen in Go um zwei verschiedene Arten. Fehler beziehen sich im Allgemeinen auf logische Fehler, die vom Programm generiert werden, oder auf unerwartete Situationen, und Ausnahmen sind im Allgemeinen Panikfehler, z. B. Indizes außerhalb der Grenzen und Absatzfehler. Fehler.

Für Fehler verwendet Golang eine sehr primitive Methode. Wir müssen jeden Fehler, der auftreten kann, manuell an den Aufrufer zurückgeben. Die folgende Schreibmethode ist in Go sehr verbreitet:

package mainimport (
    "errors"
    "fmt")func main() {
    s, err := say()
    if err != nil {
        fmt.Printf("%s\n", err.Error())
    } else {
        fmt.Printf("%s\n", s)
    }}func say() (string, error) {
    // do something
    return "", errors.New("something error")}复制代码

Dieser Typ ist der größte Das Problem bei der Schreibmethode besteht darin, dass jeder Fehler beurteilt und verarbeitet werden muss, was sehr umständlich ist. Wenn wir den Try-Catch-Mechanismus verwenden, können wir Fehler, die durch mehrere Funktionsaufrufe entstehen können, einheitlich behandeln und so ein wenig Code und Zeit sparen. Aber wir sind heute nicht hier, um den Ausnahme- und Fehlerbehandlungsmechanismus von Go zu diskutieren. Wir werden hier nur kurz darüber sprechen.

2.panic

Im Allgemeinen werden Fehler explizit vom Programm angezeigt und zurückgegeben, während Ausnahmen oft implizit und unvorhersehbar sind, wie zum Beispiel der folgende Code:

package mainimport "fmt"func main() {
    fmt.Printf("%d\n", cal(1,2))
    fmt.Printf("%d\n", cal(5,2))
    fmt.Printf("%d\n", cal(5,0)) //panic: runtime error: integer pide by zero 
    fmt.Printf("%d\n", cal(9,5))}func cal(a, b int) int {
    return a / b}复制代码
Während der dritten Berechnung tritt manchmal eine Panik auf. Dieser Fehler führt dazu, dass das Programm beendet wird und der folgende Code nicht ausgeführt wird. Natürlich kann man sagen, dass diese Art von Fehler theoretisch vorhersehbar ist und wir ihn nur innerhalb der Cal-Funktion behandeln müssen.

In der tatsächlichen Entwicklung kann es jedoch an vielen Stellen zu Panik kommen, und dies ist nicht auf den ersten Blick erkennbar. In einem Webdienst führt eine solche Panik dazu, dass der gesamte Webdienst hängen bleibt besonders gefährlich.

3.recover

Obwohl es keinen Try-Catch-Mechanismus gibt, verfügt Go tatsächlich über einen ähnlichen Wiederherstellungsmechanismus, die Funktion ist etwas schwächer und die Verwendung ist sehr einfach:

package mainimport "fmt"func main() {
    fmt.Printf("%d\n", cal(1, 2))
    fmt.Printf("%d\n", cal(5, 2))
    fmt.Printf("%d\n", cal(5, 0))
    fmt.Printf("%d\n", cal(9, 2))}func cal(a, b int) int {
    defer func() {
        if err := recover(); err != nil {
            fmt.Printf("%s\n", err)
        }
    }()
    return a / b}复制代码
Zuallererst muss jeder Verstehen Sie die Rolle von defer. Es ähnelt dem Destruktor in objektorientierter Ausführung. Es wird ausgeführt, wenn diese Funktion beendet wird, auch wenn sie durch Panik beendet wird.

Jedes Mal, wenn die Cal-Funktion beendet wird, prüft sie, ob eine Ausnahme vorliegt. Wenn sie auftritt, können wir diese behandeln, z. B. Protokolle aufzeichnen, damit das Programm weiter ausgeführt werden kann.

4. Zu beachtende Fallstricke

Im Allgemeinen wird der Verzögerungswiederherstellungsmechanismus häufig in residenten Prozessanwendungen wie Webdiensten verwendet. Andernfalls wird jeder Webanforderung eine Goroutine zugewiesen Wenn eine Anfrage in Panik gerät, hängt dies in jeder Verarbeitungssituation dazu, dass sich der gesamte Dienst aufhängt, was inakzeptabel ist. Daher muss in Webanwendungen eine Wiederherstellung verwendet werden, um sicherzustellen, dass auch bei einem Fehler in einer Anfrage andere Anfragen dies tun nicht beeinträchtigt werden. Hier verwende ich einen kleinen Codeabschnitt, um es zu simulieren:

package mainimport (
    "fmt")func main() {
    requests := []int{12, 2, 3, 41, 5, 6, 1, 12, 3, 4, 2, 31}
    for n := range requests {
        go run(n) //开启多个协程
    }

    for {
        select {}
    }}func run(num int) {
    //模拟请求错误
    if num%5 == 0 {
        panic("请求出错")
    }
    fmt.Printf("%d\n", num)}复制代码

Der obige Code kann nicht vollständig ausgeführt werden, da eine der Coroutinen unweigerlich in Panik gerät, was dazu führt, dass die gesamte Anwendung hängen bleibt und andere Coroutinen nicht mehr ausgeführt werden.

Die Lösung ist die gleiche wie oben. Wir müssen nur die Verzögerungswiederherstellung zur Ausführungsfunktion hinzufügen, und das gesamte Programm ist sehr robust. Selbst wenn eine Panik auftritt, wird es vollständig ausgeführt.

func run(num int) {
    defer func() {
        if err := recover();err != nil {
            fmt.Printf("%s\n", err)
        }
    }()
    if num%5 == 0 {
        panic("请求出错")
    }
    fmt.Printf("%d\n", num)}复制代码

Der obige Code ist nur eine Demonstration: Wenn Sie andere Coroutinen in der Ausführungsfunktion starten, kann die in dieser Coroutine auftretende Panik nicht behoben werden und führt trotzdem dazu, dass der gesamte Prozess hängt Nehmen Sie das obige Beispiel:

rrree

Ich habe eine andere Funktion über die Coroutine in der Ausführungsfunktion aufgerufen, und diese Funktion wird ebenfalls in Panik geraten. Auch wenn die Ausführungsfunktion wiederhergestellt wird, wird dies nicht der Fall sein Funktion bedeutet dies, dass wir auch „recover“ zur myPrint-Funktion hinzufügen müssen. Wenn Sie jedoch keine Coroutine zum Aufrufen der Funktion „myPrint“ verwenden, können Sie die Wiederherstellung trotzdem erfassen, indem Sie sie direkt aufrufen.

Zusammenfassend lässt sich sagen, dass der Defer-Recover-Mechanismus nur für die Panik gilt, die durch die aktuelle Funktion und die direkt aufgerufene Funktion erzeugt werden kann. Er kann die Panik anderer Coroutinen, die durch ihren Aufruf erzeugt werden, nicht verarbeiten.

Theoretisch müssen alle Orte, an denen Coroutinen verwendet werden, aufgeschoben werden, um sicherzustellen, dass Ihre Anwendung narrensicher ist. Es kann jedoch auch festgestellt werden, dass das Hinzufügen einiger Funktionen während der Entwicklung unwahrscheinlich ist Leistung.

Dasselbe gilt für den Webdienst von Go. Wenn Sie bei der Verarbeitung dieser Anfrage andere Coroutinen verwenden, müssen Sie sehr vorsichtig sein, solange eine Panik auftritt wird auflegen.

Um es zusammenzufassen: Obwohl der Ausnahmebehandlungsmechanismus von Go nicht so effizient ist wie bei vielen anderen Sprachen, kann er im Grunde die Anforderungen erfüllen. Der Beamte verbessert dies derzeit und sieht es möglicherweise in Go2.

Empfohlen: „Go-Sprach-Tutorial

Das obige ist der detaillierte Inhalt vonNehmen Sie eine kleine Falle von Golang Recover auf. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:learnku.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen