Go語言開發(七)、Go語言錯誤處理

來源:互聯網
上載者:User

Go語言開發(七)、Go語言錯誤處理

一、defer延遲函數

1、defer延遲函數簡介

defer在聲明時不會立即執行,而是在函數return後,再按照FILO(先進後出)的原則依次執行每一個defer,一般用於異常處理、釋放資源、清理資料、記錄日誌等。
每次defer語句執行時,defer修飾的函數的傳回值和參數取值會照常進行計算和儲存,但是defer修飾的函數不會執行。等到上一級函數返回前,會按照defer的聲明順序倒序執行全部defer的函數。defer所修飾函數的任何傳回值都會被丟棄。
如果一個defer所修飾函數的值為nil,則defer的函數會在函數執行時panic(異常),而不會在defer語句執行時panic。defer所修飾函數的上一級函數即使拋出異常,defer所修飾函數也會被執行的,確保資源被合法釋放。
defer延遲函數使用樣本如下:

package mainimport "fmt"func deferTest(){   defer fmt.Println(1)   defer fmt.Println(2)   fmt.Println(3)}func main() {   deferTest()//3,2,1}

2、defer延遲函數應用

A、簡化資源回收

mu.Lock() defer mu.Unlock()

defer 有一定的開銷, 為了節省效能可以避免使用的defer 
B、捕獲panic異常
Go語言中,panic用於拋出異常,,recover用於捕獲異常。
recover只能在defer語句中使用,直接調用recover是無效的。

package mainimport "fmt"func deferRecover(){   defer func () {      if r := recover(); r != nil {         fmt.Println("recover")      }   }()   fmt.Println("exception will be happen")   panic("exception has happped.")   fmt.Println("return normally")}func main() {   deferRecover()}

C、修改傳回值
defer可以用於在 return 後修改函數的傳回值。

package mainimport "fmt"func deferReturn(a,b int)(sum int){   defer func(){      sum += 100   }()   sum = a + b   return sum}func main() {   sum := deferReturn(1,6)   fmt.Println(sum)//107}

D、安全回收資源

func set(mu *sync.Mutex, arr []int, i, v int) {   mu.Lock()   defer mu.Unlock()   arr[i] = v}

如果運行時拋出切片越界異常,可以保證mu.Unlock()被調用。

二、錯誤處理

1、錯誤處理簡介

Go語言通過內建的錯誤介面提供了簡單的錯誤處理機制。
error類型是一個介面類型,定義如下:

type error interface {    Error() string}

Golang中引入error介面類型作為錯誤處理的標準模式,如果函數要返回錯誤,則傳回值類型列表中肯定包含error。

2、錯誤處理使用

package mainimport (   "fmt"   "errors")//定義一個DivideError類型type DivideError struct {   dividee int   divider int}//實現error介面func (err *DivideError) Error() error{   strFormat := `Cannot proceed, the divider is zero.dividee: %d divider: 0`   return errors.New(fmt.Sprintf(strFormat, err.dividee))}//定義除法運算func divide(vardividee int, vardivider int)(result int, errmsg error){   if vardivider == 0{      divideErr := DivideError{         dividee:vardividee,         divider:vardivider,      }      errmsg = divideErr.Error()      return 0,errmsg   }else{      return vardividee/vardivider,nil   }}func main() {   //正常情況   if result, err := divide(100, 10); err != nil{      fmt.Println(err)   }else{      fmt.Println("100/10 = ", result)   }   //當被除數為零的時候會返回錯誤資訊   if _, errorMsg := divide(100, 0); errorMsg != nil{      fmt.Println(errorMsg)   }}

三、異常處理

1、異常處理簡介

Go使用panic()函數拋出異常,在defer語句中調用recover()函數捕獲異常。

func panic(interface{})//接受任意型別參數 無傳回值 func recover() interface{}//可以返回任意類型 無參數

panic()是一個內建函數,可以中斷原有的控制流程程,進入一個panic流程中。當函數F調用panic,函數F的執行被中斷,但F中的延遲函數(必須是在panic前的已載入的defer)會正常執行,然後F函數逐層向上返回,直到發生panic的goroutine中所有調用的函數返回,此時程式退出。異常可以直接調用panic產生,也可以由執行階段錯誤產生,例如訪問越界的數組。
recover()是一個內建函數,可以讓進入panic流程中的goroutine恢複過來。recover僅在延遲函數中有效。在正常的執行過程中,調用recover會返回nil,並且沒有其它任何效果。如果當前的goroutine陷入panic,調用recover可以捕獲到panic的輸入值,並且恢複正常的執行。
一般情況下,recover()應該在一個使用defer關鍵字的函數中執行以有效截取錯誤處理流程。如果沒有在發生異常的goroutine中明確調用恢複過程(使用recover關鍵字),會導致goroutine所屬的進程列印異常資訊後直接退出。

2、異常處理使用樣本

package mainimport (   "errors"   "fmt")//定義一個DivideError類型type DivideError struct {   dividee int   divider int}//實現error介面func (err *DivideError) Error() error{   strFormat := `Cannot proceed, the divider is zero.dividee: %d divider: 0`   return errors.New(fmt.Sprintf(strFormat, err.dividee))}//定義除法運算func divide(dividee int, divider int)(result int){   defer func() {      if r := recover();r != nil{         divideErr := DivideError{            dividee:dividee,            divider:divider,         }         fmt.Println(divideErr.Error())      }   }()   result = dividee/divider   return result}func main() {   a := divide(100,0)   fmt.Println(a)}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.