Golang初级系列教程-控制结构-defer语句

DowntownGuy · · 1525 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Golang初级系列教程-控制结构-defer语句

defer 语句是用来在函数返回之前执行特定功能的关键字。有啥用处呢?在编程时,通常需要 allocate/block/lock 资源,但是当程序崩溃时,代码无法执行到 un-allocate/unblock/unlock 资源的地方,可能导致死锁等问题得发生。通过使用 defer 语句,可以保证无论什么情况发生,这些资源总是会被释放的。

在下面的代码中,假设要执行一系列的数据库操作:打开数据库连接,执行操作。之后假设,数据库操作出现异常,程序会立即返回。如果什么也不做,数据库连接将会一直持续,如果使用 defer 语句,可以保证在程序返回之前,数据库连接被正确的关闭。

package main

import "fmt"

func connectToDB () {
    fmt.Println( "ok, connected to db" )
}

func disconnectFromDB () {
    fmt.Println( "ok, disconnected from db" )
}


func doDBOperations() {
     connectToDB()
     fmt.Println("Defering the database disconnect.")
     defer disconnectFromDB() //function called here with defer
     fmt.Println("Doing some DB operations ...")
     fmt.Println("Oops! some crash or network error ...")
     fmt.Println("Returning from function here!")
     return //terminate the program
     // deferred function executed here just before actually returning, even if there is a return or abnormal termination before
}

func main() {
    doDBOperations()
}
ok, connected to db
Defering the database disconnect.
Doing some DB operations ...
Oops! some crash or network error ...
Returning from function here!
ok, disconnected from db

多个 defer 语句的执行顺序

可以声明多个 defer 语句。当声明多个是,满足后进先出(last in first out-LIFO)的执行顺序,就相当于一个栈一样。在下面的代码中,首先 defer fA(),之后 defer fB(),程序返回时,执行顺序是先执行 fB() 再执行 fA()

package main

import "fmt"

func fA() {
    fmt.Println( "this is function A" )
}

func fB() {
    fmt.Println( "this is function B" )
}

func main() {
     defer fA() //defer fA called first
     defer fB() //defer fB called second

     //program/this function ends here

     //deferred functions executed in LIFO (last in first out) order
}
this is function B
this is function A

Golang一种神奇的语言,让我们一起进步


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:DowntownGuy

查看原文:Golang初级系列教程-控制结构-defer语句

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1525 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传