go的異常處理機制

在java或php等不少面向對象的語言中, 異常處理是依靠throw、catch來進行的。在go語言中,panic和recover函數在做用層面分別對等throw和catch語句,固然也存在不一樣之處。php

從設計層面來看,panic和recover函數適用於那些真正的異常(例如整數除0),而throw catch finally機制經常被用來處理一些業務層面的自定義異常。所以在go語言中,panic和recover要慎用。java

上述兩種異常機制的使用中,在處理異常時控制流程的走向也是類似的。數組

下面將分別舉例說明:函數

try catch finally機制設計

try{
        throw new Exception();
    } catch(Exception $e) {
        do something ...
    } finally {
       
    }

這種機制中,咱們把可能拋出異常的語句或拋出自定義異常的語句放置到try語句塊中,而在catch塊中,咱們將上述語句拋出的異常捕獲,針對不一樣的異常進行報警或log等處理。以後,控制流程進入到finally語句塊中。若沒有finally語句,控制流程將進入到catch以後的語句中。也就是說,在這種機制中,控制流程是轉移到同一層級中異常捕獲以後的語句中。code

panic recover defer機制對象

在go的異常機制中,panic能夠將原有的控制流程中斷,進入到一個"恐慌"流程。這種恐慌流程能夠顯式調用panic()函數產生或者由運行時錯誤產生(例如訪問越界的數組下標)。panic會在調用它的函數中向本層和它的全部上層逐級拋出,若一直沒有recover將其捕獲,程序退出後會產生crash;若在某層defer語句中被recover捕獲,控制流程將進入到recover以後的語句中。進程

/* example 1 */
    package main
    import (
        "fmt"
    )

    func f() {
        defer func() {
            fmt.Println("b")
            if err := recover();err != nil {
                fmt.Println(err)
            }
            fmt.Println("d")
        }()
        fmt.Println("a")
        panic("a bug occur")
        fmt.Println("c")
    }

    func main() {
        f()
        fmt.Println("x")
    }

在上述舉例中,輸出結果爲:io

a
    b
    a bug occur
    d
    x

這說明,在f函數中拋出的panic被本身defer語句中的recover捕獲,而後控制流程進入到recover以後的語句中,即打印d、打印x,以後進程正常退出。import

/* example 2 */
    package main
    import (
        "fmt"
    )

    func g() {
        defer func() {
            fmt.Println("b")
            if err := recover();err != nil {
                fmt.Println(err)
            }
            fmt.Println("d")
        }()
        f()
        fmt.Println("e")
    }

    func f() {
        fmt.Println("a")
        panic("a bug occur")
        fmt.Println("c")
    }

    func main() {
        g()
        fmt.Println("x")
    }

上述案例的輸出結果是:

a
    b
    a bug occur
    d
    x

進程經歷了這樣一個過程:f()中拋出panic,因爲自身沒有定義defer語句,panic被拋到g()中。g()的defer語句中定義了recover,捕獲panic後並執行完defer剩餘的語句,以後控制流程被轉交到main()函數中,直至進程結束。

相關文章
相關標籤/搜索