Go 學習之路:異常處理defer,panic,recover

Go沒有像Java那樣的異常機制,它不能拋出異常。由於設計者們認爲,將異常與控制結構混在一塊兒容易使得代碼變得混亂。因而乎引入Exception處理: defer,panic,recover;

簡單描述:Go中能夠拋出一個panic的異常,而後在defer中經過recover捕獲這個異常,而後正常處理。

例子代碼:html

package main

import "fmt"

func demo(){
    fmt.Println("Welcome, my name is fudomine")
    panic(400)
    fmt.Println("Hello")
}

func main(){
    defer func(){
        fmt.Println("defer start")
        errorMsg := recover()
        fmt.Println("Error msg :", errorMsg)
        fmt.Println("defer end")
    }()
    demo()
}

運行結果
運行結果git

defer

defer 英文原意: vi. 推遲;延期;服從 vt. 使推遲;使延期。web

  • Go語言中內置函數;相似於C/PHP的析構函數,但它不是針對對象而是函數;
  • 容許在函數中添加多個defer語句。當函數執行到最後時,這些defer語句會按照逆序執行,最後該函數返回(相似堆棧,先進後出)。
  • 調用時須在程序結束前調用,簡單來講讓defer語句在return/panic前寫入至內存中;
func demo()(str string){
    str = "Hello"
    defer func() {
        str = "Welcome, my  name is fudomine"
    }()
    return
}

返回結果:Welcome, my name is fudomine編程

func demo()(str string){
    str = "Hello"
    return
    defer func() {
        str = "Welcome, my  name is fudomine"
    }()
    return
}

返回結果:Hellodom

可能會有小夥伴本身編寫代碼後,答案不一致;爲此特貼出不同結果的例子代碼並進行分析;函數

func demo()(string){
    str := "Hello"

    defer func() {
        str = "Welcome, my  name is fudomine"
    }()
    return str
}

緣由:defer 中return xxx這一條語句並非一條原子指令,而上面結果是由於初始化時候就聲明輸出類型是*T(指針);spa

拆分爲:設計

  • 返回值 = xxx
  • 調用defer函數
  • 空的return

詳細請參考下《深刻解析GO》一文指針

panic

panic 英文原意:n. 恐慌,驚慌;大恐慌 adj. 恐慌的;沒有理由的 vt. 使恐慌 vi. 十分驚慌code

  • Go是一個內建函數,能夠中斷原有的控制流程,進入一個異常的流程中。當函數 Func 調用 panic ,函數Func 的執行被中斷,可是 Func 中的延遲函數會正常執行,而後Func 返回到調用它的地方。在調用的地方, Func 的行爲就像調用了 panic 。這一過程繼續向上(只有剛纔defer寸在內存中,將會被調用),直到發生 panic 的 goroutine 中全部調用的函數返回,此時程序退出。

recover

recover 英文原意: vt. 恢復;彌補;從新得到 vi. 恢復;勝訴;從新得球 n. 還原至預備姿式

  • Go是一個內建的函數,可讓進入使人恐慌的流程中的 goroutine 恢復過來。 recover 僅在延遲函數中有效。在正常的執行過程當中,調用 recover 會返回 nil ,而且沒有其它任何效果。若是當前的 goroutine 陷入恐慌,調用recover 能夠捕獲到 panic 的輸入值,而且恢復正常的執行。

參考文獻
《go web編程》

做者:不動峯
博客園: http://www.cnblogs.com/mylly/ 版權全部,歡迎保留原文連接進行轉載:)
相關文章
相關標籤/搜索