Golang的異常處理實戰篇


          Golang的異常處理實戰篇

                             作者:尹正傑

版權聲明:原創作品,謝絕轉載!否則將追究法律責任。

 

 

  Go語言的異常捕獲要比Python中簡單的多,它沒有Python中那么多復雜的異常類型及繼承體系。接下來我們來一起體驗一下Golang的異常處理。

 

 

一.代碼運行時出錯應該怎樣處理呢?

1>.算數除零異常案例

package main

import (
    "fmt"
)

func main() {
    //定義除數
    a := 20

    //定義被除數
    b := 0

    //除數不能為0,編譯時並不會報錯,但是在代碼運行時會報錯喲~
    c := a / b

    //由於上面的代碼執行報錯啦,該行代碼不會被執行
    fmt.Printf(" %d ➗ %d = %d\n", a, b, c)
}

2>.數組索引越界異常案例

package main

import (
    "fmt"
)

func myArr(index int) {

    //定義數組
    var arr [10]int

    //數組這里賦值時可能會存在一個風險,即索引越界異常
    arr[index] = 123

    fmt.Println(arr)
}

func main() {
    myArr(12)
}

 

二.Go語言中自定義異常接口

1>.使用errors自定義異常消息(並不會使得程序崩潰)

package main

import (
    "errors"
    "fmt"
)

func div(x int, y int) (res int, err error) {

    if y == 0 {
        /*
            Go語言引入了一個關於錯誤處理的標准模式,即error接口,該接口需要導入"errors"包:
                errors接口適合返回可控的錯誤,即我們知道在某個代碼塊中可能會出現的異常。
        */
        err = errors.New("div函數除零異常...")
        return
    }
    res = x / y
    return
}

func main() {
    a := 10
    b := 0

    /*
        res:
            用來接收運算結果
        err:
            用來接收錯誤消息
        nil:
            表示空,"if err != nil"表示變量err接收的錯誤消息是否為空。
    */
    res, err := div(a, b)
    if err != nil {
        fmt.Println(err)
        //log.Fatal(err) //我們也可以使用log包來幫助咱們輸出錯誤,它會在錯誤消息簽名自動加上日期時間
    } else {
        fmt.Println(res)
    }

    fmt.Println("代碼執行完畢")
}

2>.使用panic自定義異常消息(程序會崩潰)

package main

import (
    "fmt"
)

func myArr2(index int) {

    //定義數組
    var arr [10]int

    if index >= 10 {
        /*
            panic函數與errors接口不同:
                (1)使用panic時無需導入包;
                (2)若出現異常,使用panic封裝異常消息時,會直接導致程序運行結束,換句話說,error是一般性錯誤,而panic函數返回的是讓程序崩潰的錯誤

            溫馨提示:
                一般而言,當panic異常發生時,程序會中斷運行。隨后,程序崩潰並輸出日志消息。日志信息包括panic value和函數調用的堆棧跟蹤信息
                當然,如果直接調用內置的panic函數也會引發panic異常,panic函數接收任何值作為參數。
        */
        panic("請注意,index > 10,出現了索引越界異常...(index的取值范圍0~9)")
    }

    //上面使用了panic接口封裝了異常處理錯誤,因此如果代碼到這一行說明沒有索引越界異常
    arr[index] = 123
    fmt.Println(arr)
}

func main() {

    myArr2(12)

    fmt.Println("代碼執行完畢")
}

 

三.使用recover進行異常捕獲

1>.defer延遲調用

package main

import (
    "fmt"
)

func main() {

    /*
        defer語句被用於預定對一個函數的調用。可以把這類被defer語句調用的函數稱為函數。

        defer的應用場景:
            (1)釋放占用的資源;
            (2)捕獲異常處理
            (3)輸出日志

        溫馨提示:
            如果一個函數中有多個defer語句,它們會以LIFO(后進先出)的順序執行。

        先不要運行代碼,你先猜猜下面的代碼的執行順序。
    */
    defer fmt.Println("\thttps://www.cnblogs.com/yinzhengjie/")

    fmt.Println("我的名字叫尹正傑,英文名叫'Jason Yin'.愛好開源技術.")

    defer fmt.Println("\thttps://www.cnblogs.com/yinzhengjie2020")

    fmt.Println("我的博客是:")
}

2>.defer結合recover進行錯誤攔截

package main

import "fmt"

func test3(index int) {
    /*
        錯誤攔截要在產生錯誤前設置,因此建議大家把錯誤攔截的函數放在函數內部的首行定義。
    */
    defer func() {
        /*
            運行時panic異常一旦被引發就會導致程序崩潰
            Go語言提供了專用於"攔截"運行時panic的內建函數"recover"。
            它可以使當前的程序從運行時panic的狀態中恢復並重新獲得流程控制權,歡聚話說,通過recover進行不可控的錯誤攔截,重新獲取程序的控制權
        */
        err := recover()
        if err != nil {
            fmt.Println(err)
        }
    }()

    /*
        定義容量為10的數組
    */
    var arr [10]int

    if index >= 10 {
        panic("請注意,index > 10,出現了索引越界異常...(index的取值范圍0~9)")
    }

    arr[index] = 123

    fmt.Println(arr)
}

func main() {
    test3(5)
    test3(12)
    fmt.Println("代碼執行完畢")
}

 3>.面試題(請根據下面代碼手寫出輸出結果)

package main

import (
    "fmt"
)

func f1() (int, error) {
    defer fmt.Println(1)
    defer fmt.Println(2)
    fmt.Println(3)
    return fmt.Println(4)
}

func f2() (int, error) {
    defer fmt.Println(5)
    defer fmt.Println(6)
    fmt.Println(7)
    f1()

    defer func() (int, error) {
        defer fmt.Println(8)
        fmt.Println(9)
        return fmt.Println(10)
    }()

    return fmt.Println(11)
}

func main() {
    f2()
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM