defer 、panic、recover 用法,以及異常處理
defer 延遲執行語句
import (
"errors"
"fmt"
"testing"
func TestDefer(t *testing.T) {
//defer 延遲執行語句
fmt.Println("start")
defer fmt.Println("go")
defer fmt.Println("go")
defer fmt.Println("Let's")
defer fmt.Println("end")
//start
//end
//Let's
//go
//go
}
defer在命名傳回值和匿名傳回方法中表現不一樣
func fn1() (x int) {
x = 5
defer func() {
x++
}()
return x //6
}
func fn2() int {
var a int = 5
defer func() {
a++
}()
return a //5
}
func fn3() (y int) {
x := 5
defer func() {
x++
}()
return x //5
}
func fn4() (x int) {
defer func(x int) {
x++
}(x)
return 5 //5
}
defer 注冊要延遲執行方法時,該方法所有的參數都需要确定其值
func calc(str string, a, b int) int {
sum := a + b
fmt.Println(str, a, b, sum)
return sum
}
func TestCalc(t *testing.T) {
x := 1
y := 2
defer calc("AA", x, calc("A", x, y))
x = 10
defer calc("BB", x, calc("B", x, y))
}
1.注冊順序
defer calc(“AA”, x, calc(“A”, x, y))
defer calc(“BB”, x, calc(“B”, x, y))
2.執行順序
defer calc(“BB”, x, calc(“B”, x, y))
defer calc(“AA”, x, calc(“A”, x, y))
3.執行結果
A 1 2 3
B 10 2 12
BB 10 12 22
AA 1 3 4
panic/recover 以及異常處理
panic/recover 模式來處理錯誤
panic 可以在作任何地方引發,但recover 隻有在defer 調用的方法中有效
func test1() {
fmt.Println("異常開始")
}
func test2() {
defer func() {
err := recover() //收集異常
if err != nil {
fmt.Println("err:", err)
}
}()
panic("這裡有錯誤") //抛了異常
}
func TestException(t *testing.T) {
test1()
test2()
fmt.Println("異常測試結束")
}
執行結果
模拟讀取檔案失敗,異常處理
func TestException(t *testing.T) {
doErr() //檔案不存在
fmt.Println("haha") //haha
}
func readfile(f string) error {
if f == "main.go" {
return nil
} else {
return errors.New("檔案不存在") //注意引入error包
}
}
func doErr() {
defer func() {
e := recover()
fmt.Println(e) //檔案不存在
}()
err := readfile("demo.gp")
if err !=nil{
panic(err)
}
}