GO语言延迟函数defer用法详解

go语言中defer最主要的目的是在函数执行完毕后及时的释放资源

入门案例

  1. package main
  2.  
  3. import “fmt”
  4.  
  5. func sum(n1 int, n2 int) int {
  6.      //当执行到defer时,会将defer后面的语句压入到独立的栈中(我们取名为defer栈吧)
  7.      //当函数执行完毕后,再从defer栈,先进后出的方式出栈然后执行
  8.      defer fmt.Println(“ok1 n1=”,n1) // 3. n1
  9.      defer fmt.Println(“ok2 n2=”,n2) //2. n2
  10.      res := n1 + n2 //res = 30,首先执行
  11.      fmt.Println(“ok3 res=”,res) // 1. res = n1 + n2
  12.      return res
  13. }
  14.  
  15. func main(){
  16.      res := sum(10,20)
  17.      fmt.Println(“main res=”,res)
  18. }

-1

main方法调用sum函数

代码执行到第一个defer后,编译器(系统)会将第一个defer这段压入到defer的栈中(暂时不执行)

注意事项

  • 当ggo执行到一个defer时,不会立刻执行defer后的语句,而是将defer后的语句压入一个独立的栈中,然后继续执行函数下一条语句
  • 当执行完毕后,再从defer栈(只是为了理解这么叫,实际其实只是一个独立的栈),依次从栈顶取出语句执行(先进后出原则)
  • defer将语句放入栈时,也会将相关的值拷贝同时入栈(入栈时是什么值就是什么值)
  1. package main
  2.  
  3. import “fmt”
  4.  
  5. func sum(n1 int, n2 int) int {
  6.      //当执行到defer时,会将defer后面的语句压入到独立的栈中(我们取名为defer栈吧)
  7.      //当函数执行完毕后,再从defer栈,先进后出的方式出栈然后执行
  8.      defer fmt.Println(“ok1 n1=”,n1) //n1 = 10
  9.      defer fmt.Println(“ok2 n2=”,n2) //n2 = 20
  10.      n1++ //添加代码: n1++
  11.      n2++ //添加代码: n2++
  12.      res := n1 + n2
  13.      fmt.Println(“ok3 res=”,res) //res = 32
  14.      return res
  15. }
  16.  
  17. func main(){
  18.      res := sum(10,20)
  19.      fmt.Println(“main res=”,res) //结果还是会被影响 res = 32
  20. }

结果

-2

defer最佳实践

defer主要的价值是在当函数执行完毕后,可以及时释放函数创建的资源

  1. //示意代码
  2. func test(){
  3.      //关闭文件资源
  4.      file = openfile(文件名)
  5.      defer file.close()
  6.      //其他代码
  7.      //连接的数据库还是可以使用的
  8. }
  1. func test(){
  2.      //释放数据库资源
  3.      connect = openDatabase()
  4.      defer connect.close()
  5.      //其他代码
  6.      //连接的数据库还是可以使用的
  7. }
  • 在golang编程中的通常的做法是,创建资源后,比如(打开了文件,获取了数据库连接或者时锁等资源)可以执行defer语句来进行关闭(函数执行完后才从独立的栈中释放关闭资源)
  • defer可以继续使用创建的资源
  • 当函数执行完后,系统会依次从这个独立的栈中取出语句或关闭资源

到此这篇关于GO语言延迟函数defer用法详解的文章就介绍到这了,更多相关GO defer延迟函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

标签

发表评论