GO-異常處理
阿新 • • 發佈:2020-10-28
目錄
err介面
Go語言引入了一個關於錯誤處理的標準模式,即error介面,它是Go語言內建的介面型別,該介面的定義如下:
type error interface {
Error() string
}
呼叫對應介面
err:=errors.New("this is normal err")
fmt.Println(err.Error())
err2:=fmt.Errorf("this is normal err")
fmt.Println(err2)
案例:除數b為0時
package main import ( "errors" "fmt" ) func main() { //接收錯誤資訊和正確資訊 result,err := test(5,0) //加了判斷,如果沒有錯誤err=nil if err!=nil{ fmt.Println(err) }else { fmt.Println(result) } } //b為0時丟擲異常 func test(a,b int) (result int, err error) { //返回錯誤資訊 err = nil if b==0{ err =errors.New("b不能為0") }else { result = a/b } return }
panic函式
error返回的是一般性的錯誤,但是panic函式返回的是讓程式崩潰的錯誤。
一般而言,當panic異常發生時,程式會中斷執行。
所以,我們在實際的開發過程中並不會直接呼叫panic( )函式,但是當我們程式設計的程式遇到致命錯誤時,系統會自動呼叫該函式來終止整個程式的執行,也就是系統內建了panic函式。
案例
package main import "fmt" func main() { test1() test2() test3() } func test1() { fmt.Println("test1") } func test2() { panic("panic test2") //程式中斷 } func test3() { fmt.Println("test3") } 結果: test1 panic: panic test2 goroutine 1 [running]: main.test2(...)
defer延遲
總結
關鍵字 defer⽤於延遲一個函式的執行,呼叫了,但是沒有執行,也會完成引數的傳遞
如果一個函式中有多個defer語句,它們會以後進先出的順序執行。
注意,defer語句只能出現在函式的內部。
defer fmt.Println("333")
defer fmt.Println("222")
defer fmt.Println("111")
依次輸出順序:111,222,333
defer與匿名函式結合使用
案例1:無引數
package main import "fmt" func main() { a := 10 b := 20 defer func() { fmt.Println("匿名函式a", a) fmt.Println("匿名函式b", b) }() a = 100 b = 200 fmt.Println("main函式a", a) fmt.Println("main函式b", b) } 結果: main函式a 100 main函式b 200 匿名函式a 100 匿名函式b 200
案例二:有引數
package main
import "fmt"
func main() {
a := 10
b := 20
//呼叫了,也傳引數了,但是沒有執行
defer func(a,b int) { //新增引數
fmt.Println("匿名函式a", a)
fmt.Println("匿名函式b", b)
}(a,b) //傳引數
a = 100
b = 200
fmt.Println("main函式a", a)
fmt.Println("main函式b", b)
}
結果:
main函式a 100
main函式b 200
匿名函式a 10
匿名函式b 20
recover防止程式中斷
執行時panic異常一旦被引發就會導致程式崩潰。這當然不是我們願意看到的,因為誰也不能保證程式不會發生任何執行時錯誤。
Go語言為我們提供了專用於“攔截”執行時panic的內建函式——recover。它可以是當前的程式從執行時panic的狀態中恢復並重新獲得流程控制權。
注意:recover只有在defer呼叫的函式中有效。
func testA() {
fmt.Println("testA")
}
func testB(x int) {
//設定recover()
//在defer呼叫的函式中使用recover()
defer func() {
//防止程式崩潰
//recover()
//fmt.Println(recover())
//加了一層判斷
if err:=recover();err!=nil {
fmt.Println(err)
}
}() //匿名函式
var a [3]int
a[x] = 999
}
func testC() {
fmt.Println("testC")
}
func main() {
testA()
testB(0) //發生異常 中斷程式
testC()
}