0
点赞
收藏
分享

微信扫一扫

go基础之Deferred函数

当执行到该条语句时,函数和参数表达式得到计算,但直到包含该defer语句的函数执行完毕时,defer后的函数才会被执行,不论包含defer语句的函数是通过return正常结束,还是由于panic导致的异常结束。你可以在一个函数中执行多条defer语句,它们的执行顺序与声明顺序相反。defer语句经常被用于处理成对的操作,如打开、关闭、连接、断开连接、加锁、释放锁。通过defer机制,不论函数逻辑多复杂,都能保证在任何执行路径下,资源被释放。释放资源的defer应该直接跟在请求资源的语句后。

package ioutil

func ReadFile(filename string) ([]byte, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
return ReadAll(f)
}

被延迟执行的匿名函数甚至可以修改函数返回给调用者的返回值:defer后的函数不带参数,就会延后处理,如果是带参数,会实时计算。

func double(x int) (result int) {
defer func() { fmt.Printf("double(%d) = %d\n", x,result) }()
return x + x
}

func triple(x int) (result int) {
defer func() { result += x }()
return double(x)
}

fmt.Println(triple(4)) // "12"

输出

double(4) = 8

12

defer有三个规则

1、defer声明时,其后面函数参数会被实时解析。

package main

import "fmt"

func pr(i int) {
fmt.Println("pr", i)
}

func main() {
var i int = 1
defer pr(i) //有参数,所以i就是1
i++
defer func() {
fmt.Println("main", i) //没参数,所以调用它的时候i是3
}()
i++
}

输出

main 3

pr 1

2、defer执行顺序为先进后出,从上面例子中可以知道最下面的先执行

3、defer可以读取函数的有名返回值

package main

import "fmt"

func fun1() (i int) {
defer func() {
i = i + 10
}()
return 0 //返回的变量i,正好和函数内部对应。
}

func main() {
fmt.Println(fun1())
}

输出

10

举报

相关推荐

0 条评论