关于defer说明,官方文档这样描述:
A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.
该说明调用defer函数用于释放资源,会在函数返回之前那一刻执行。即使goroutine产生painc。
在开发过程中,我们经常使用defer命令字。比如在连接数据库、加锁等操作时候,会使用defer来释放数据库资源、释放锁等。
rows, err := handler.Query(sql)
if err != nil {
Errorln("Mysql query error, msg:%s ", err.Error())
return
}
defer rows.Close()
updateShareMutex.Lock()
defer updateShareMutex.Unlock()
在正常开发场景时候,主要defer关闭资源时候要在判断err之后,避免空指针。比如把释放资源场景中的defer位置放错,会引起空指针异常。
如果简单了解defer使用是不够的,尤其是跟带命名的返回参数一起使用时,可能会踩到一些坑。
func b(){
for i := 0; i < 4; i++ {
defer fmt.Print(i) // 3210
}
}
func a(){
i := 0
defer fmt.Println(i) // 0
i++
return
}
func c() (i int) {
// return语句不是一条原子调用,return xxx其实是赋值+ret指令
// i = 1
// defer被插入到return之前执行,也就是赋返回值和ret指令之间
defer func() {
i++
}()
// return
return 1
} // 结果为:2
func d() (r int){
t := 5
// 赋值指令
// r = t
defer func(){ // defer被插入到赋值与返回之间执行,这个例子中返回值r没有被修改过
t = t + 5
}()
// return
return t
}
func e() (r int){
// 给返回值赋值
// r = 1
defer func(r int) { // 这里改的r是传值传进去的r, 不会改变要返回的那个r值
r = r + 5
}(r)
// return
return 1
}
从上面实例分析函数返回的过程是这样的:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。