defer 、panic、recover 用法,以及异常处理
defer 延迟执行语句
import (
"errors"
"fmt"
"testing"
func TestDefer(t
*testing
.T
) {
fmt
.Println("start")
defer fmt
.Println("go")
defer fmt
.Println("go")
defer fmt
.Println("Let's")
defer fmt
.Println("end")
}
defer在命名返回值和匿名返回方法中表现不一样
func fn1() (x
int) {
x
= 5
defer func() {
x
++
}()
return x
}
func fn2() int {
var a
int = 5
defer func() {
a
++
}()
return a
}
func fn3() (y
int) {
x
:= 5
defer func() {
x
++
}()
return x
}
func fn4() (x
int) {
defer func(x
int) {
x
++
}(x
)
return 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")
}
func readfile(f
string) error {
if f
== "main.go" {
return nil
} else {
return errors
.New("文件不存在")
}
}
func doErr() {
defer func() {
e
:= recover()
fmt
.Println(e
)
}()
err
:= readfile("demo.gp")
if err
!=nil{
panic(err
)
}
}