GO学习笔记——defer调用(21)

编程入门 行业动态 更新时间:2024-10-08 12:41:19

GO<a href=https://www.elefans.com/category/jswz/34/1770117.html style=学习笔记——defer调用(21)"/>

GO学习笔记——defer调用(21)

defer调用也是一种流程控制语句,经常用来调用一些资源处理函数。

defer语句确保被执行的语句具有下面的调用时机

defer调用必须出现在函数内,并且在该函数返回之前才回去执行defer调用的函数


 给一个示例来看一下

func testdefer(){defer fmt.Println("calling last")fmt.Println("calling first")
}func main() {testdefer()
}

执行结果

calling first
calling last

可见,defer后面的函数调用在程序最后才去执行。

 

那如果有多个defer语句怎么办呢?defer执行顺序其实相当于一个defer栈,采用的是先进后出的原则

func testdefer(){defer fmt.Println("calling last")defer fmt.Println("calling next")fmt.Println("calling first")
}func main() {testdefer()
}

执行结果

calling first
calling next
calling last

 

延迟方法

不仅是函数,方法也可以作为defer的调用

type student struct {name stringage int
}func (s student) print() {fmt.Println(s.name)
}func testdefer(){s := student{"pigff",21}defer s.print()fmt.Println(s.age)	//会先执行这句,打印21
}func main() {testdefer()
}

执行结果

21
pigff

 

defer的实参取值

defer调用的函数内的参数值,并不是在真正调用defer时确定的,而是在执行到defer时就确定了。

还是上面的例子

type student struct {name stringage int
}func (s student) print() {fmt.Println(s.name)
}func testdefer(){s := student{"pigff",21}defer s.print()		//执行到defer语句时,name还是pigff,所以在最好defer调用时,也是这个s.name = "Kobe"	//这里改变名字,下一句打印的是Kobes.print()
}func main() {testdefer()
}

执行结果

Kobe
pigff

这里在执行到defer语句的时候,s.name还是pigff,所以在最后defer调用时s.name依旧还是pigff,并不是在程序后面改变的Kobe。

 

再换一个简单的例子

func  print(a int) {fmt.Println(a)
}func testdefer(){a := 5defer print(a)    //在执行到这一句的时候a还是5a = 10print(10)
}func main() {testdefer()
}

执行结果

10
5

因此,需要注意defer的实参取值,是在执行时确定的,而不是在调用时。

 

关于defer的实际使用场景

其实在学C++的智能指针的时候,学到过类似的概念。

当我们申请了资源的时候,比如锁,数据库连接,加了锁我们得解锁,建立了连接我们得关闭。假设我们确实写了释放资源的语句,但是如果程序突然在执行释放语句之前return了,比如说报出panic了导致程序中断等,这个时候释放资源的语句就没有被调用了,那么我们申请的资源就会没有释放,长此以往就会导致资源泄漏等很多问题。

虽说在程序运行结束时资源都会全部释放,但是一般服务器程序是不会经常关闭的。

所以defer调用保证调用的函数肯定会在函数结束之前被执行,即使程序报了panic中断,defer调用依旧会被执行。

这就是defer调用的好处,它经常与释放资源等操作配套执行,确保资源被释放。

常用的场景如下(都是配套的,我们在申请资源时就应该使用defer写释放资源的语句)

  • 打开文件,关闭文件
  • 加锁,解锁
  • 建立连接,释放连接

更多推荐

GO学习笔记——defer调用(21)

本文发布于:2024-02-14 08:54:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1762521.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:学习笔记   defer

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!