在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
defer defer是go提供的一种资源处理的方式。defer的用法遵循3个原则
1 func a() { 2 i := 0 3 defer fmt.Println(i) 4 i++ 5 return 6 }
func b() { for i := 0; i < 4; i++ { defer fmt.Print(i) } }
func c() (i int) { defer func() { i++ }() return 1 }
针对上述的第三点有如下三种情况: 例1: 例2: 例3: 函数返回的过程是这样的:先给返回值赋值,然后再调用defer表达式,最后才是返回到调用函数中 先看例1,它可以改写成这样: func f() (result int) { result = 0 //return语句不是一条原子调用,return xxx其实是赋值+ret指令 func() { //defer被插入到return之前执行,也就是赋返回值和ret指令之间 result++ }() return } 所以这个返回值是1。 再看例2,它可以改写成这样: func f() (r int) { t := 5 r = t //赋值指令 func() { //defer被插入到赋值与返回之间执行,这个例子中返回值r没被修改过 t = t + 5 } return //空的return指令 } 所以这个的结果是5。 最后看例3,它改写后变成: func f() (r int) { r = 1 //给返回值赋值 func(r int) { //这里改的r是传值传进去的r,不会改变要返回的那个r值 r = r + 5 }(r) return //空的return } 所以这个例子的结果是1。
panic和recover panic和recover的使用需要遵循以下原则:
使用recover捕获程序中的错误的用法如下 package main import ( "fmt" "time" ) func main() { f() fmt.Println("end") } func f() { defer func() { //必须要先声明defer,否则不能捕获到panic异常 fmt.Println("defer start") if err := recover(); err != nil { fmt.Println(err) //这里的err其实就是panic传入的内容,"bug" } fmt.Println("defer end") }() for { fmt.Println("func begin") a := []string{"a", "b"} fmt.Println(a[3]) // 越界访问,肯定出现异常 panic("bug") // 上面已经出现异常了,所以肯定走不到这里了。 fmt.Println("func end") // 不会运行的. time.Sleep(1 * time.Second) } } 输出结果如下 1 func begin 2 defer start 3 runtime error: index out of range 4 defer end 5 end
参考: |
请发表评论