分享
  1. 首页
  2. 文章

golang关于defer的问题

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

要弄明白defer首先得搞清楚闭包和局部作用域。

闭包

闭包是匿名函数与匿名函数所引用环境的组合。
看一个例子:

func main() {
 n := 0
 f := func() {
 n += 1
 }
 f()
 fmt.Println("n = ", n)
}
// output: n = 1
func main() {
 n := 0
 f := func(n int) {
 n += 1
 }
 f(n)
 fmt.Println("n = ", n)
}
// output n = 0 

看了以上两个例子,大概可以对闭包有个简单的认识,匿名函数可以直接引用上一级函数内的变量, 所以可以看到第一个例子进行 n+1 操作修改了main函数中的n的值。
而第二个函数中的匿名函数需要传参n, 因为go中的传参都是值类型的, 所以不会修改外部变量n 输出扔为0。

这篇文章的重点不是为了介绍闭包,所以这里只介绍这么多,有兴趣可以去网上找相关文章查阅。

继续说defer

  • defer调用过程:
  1. 返回值为 xxx
  2. 调用defer函数
  3. return

其实defer的调用相当于一个内部函数的调用,可以看以下例子:

func f() (r int) {
 // go函数编译的时候已经将带名字的返回值变量给初始化
 // 所以在返回值的时候调用defer函数会改变其值
 r = 5
 defer func() {
 r = r + 5
 }()
 return
}
// output 10 
// 与闭包中的第一个例子类似,defer 函数修改了r的值
// 返回值r = 5
// 调用defer函数 r += 5 => r = 10
// return r => 10

例2

func f() (r int) {
 t := 5
 defer func() {
 t = t + 5
 }()
 return t
}
// 结合上边说的defer调用过程:
// 返回值 r = t 对r进行赋值操作 
// defer 修改 t 的值 t+= 5 => t =10
// return r => r = 5 

例3

func f() int {
 t := 5
 defer func() {
 t = t + 5
 }()
 return t
}
// 同样结合调用过程:
// 返回值赋值 这里的返回值是个匿名变量, 假设这个匿名变量为NoName = t = 5
// defer 调用 t+= 5 => t = 10
// 返回 NoName = 5

例4

func f3() (r int) {
 // defer的时候 r为0
 defer func(r int) {
 r = r + 5
 }(r)
 return 1
}
// 结合defer调用过程
// 返回值 r 赋值 r = 1 
// 带参数r的匿名函数 进行defer调用, 参考闭包中的例子2 知道 r的传入不会影响外部r的值, 所以匿名函数外部的 r扔为1
// 返回 r的值 1 

以上, 即为defer的几种调用。

文章内容有所参考, 如下:
Golang之轻松化解defer的温柔陷阱


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

本文来自:简书

感谢作者:五知小白羊

查看原文:golang关于defer的问题

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

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

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏