当前位置:首页 > 科技  > 软件

解密defer语句:避免踩坑,掌握延迟执行的正确姿势

来源: 责编: 时间:2023-11-19 10:30:28 407观看
导读基本概念Go语言的延迟语句defer有哪些特点?通常在什么情况下使用?Go语言的延迟语句(defer statement)具有以下特点:延迟执行:延迟语句会在包含它的函数执行结束前执行,无论函数是正常返回还是发生异常。后进先出:如果有多个


QYp28资讯网——每日最新资讯28at.com

基本概念

Go语言的延迟语句defer有哪些特点?通常在什么情况下使用?QYp28资讯网——每日最新资讯28at.com

Go语言的延迟语句(defer statement)具有以下特点:QYp28资讯网——每日最新资讯28at.com

  1. 延迟执行:延迟语句会在包含它的函数执行结束前执行,无论函数是正常返回还是发生异常。
  2. 后进先出:如果有多个延迟语句,它们会按照后进先出(LIFO)的顺序执行。也就是说,最后一个延迟语句会最先执行,而第一个延迟语句会最后执行。

通常情况下,延迟语句在以下情况下使用:QYp28资讯网——每日最新资讯28at.com

  1. 资源释放:延迟语句可以用于在函数返回前释放打开的文件、关闭数据库连接、释放锁等资源,以确保资源的正确释放,避免资源泄漏。
  2. 错误处理:延迟语句可以用于处理函数执行过程中可能发生的错误。通过在函数开始时设置延迟语句,在函数返回前检查错误并进行相应的处理,可以简化错误处理的逻辑。
  3. 日志记录:延迟语句可以用于在函数返回前记录日志或执行其他的调试操作,以便在函数执行过程中收集相关的信息。

延迟语句的使用可以提高代码的可读性和可维护性,同时确保资源的释放和清理操作按照逆序进行。它是Go语言中一种常用的编程技巧,用于处理资源管理和错误处理等场景。QYp28资讯网——每日最新资讯28at.com

避坑之旅

实际开发中defer的使用并不像前面介绍的这么简单,defer用不好,会陷入泥潭。QYp28资讯网——每日最新资讯28at.com

下面我从两个角度带大家避坑:QYp28资讯网——每日最新资讯28at.com

  1. 首先拆解一下延迟语句的执行,注意Go语言的return语句不是原子性的;
  2. 另外重点和大家分享一下defer语句后面使用匿名函数和非匿名函数的区别。

拆解延迟语句

避免陷入泥潭的关键是必须深刻理解下面这条语句:QYp28资讯网——每日最新资讯28at.com

return xxx

上面这条语句经过编译之后,实际上生成了三条指令:QYp28资讯网——每日最新资讯28at.com

1)返回值 =xxx。QYp28资讯网——每日最新资讯28at.com

2)调用 defer 函数。QYp28资讯网——每日最新资讯28at.com

3)空的 return。QYp28资讯网——每日最新资讯28at.com

第1和第 3 步是return语句生成的指令,也就是说return并不是一条原子指令;QYp28资讯网——每日最新资讯28at.com

第2步是 defer 定义的语句,这里可能会操作返回值,从而影响最终结果。QYp28资讯网——每日最新资讯28at.com

下面来看两个例子,试着将return 语句和 defer语句拆解到正确的顺序。QYp28资讯网——每日最新资讯28at.com

第一个例子:

func f()(r int){  t:=5  defer func(){    t=t+5    }()      return t}

拆解后:QYp28资讯网——每日最新资讯28at.com

func f()(r int){  t:=5    //1,赋值指令  r=t  // 2.defer 被插入到赋值与返回之间执行,这个例子中返回值r没被修改过   func(){    t=t+5    }()      //3.空的 return 指令  return  }

这里第二步实际上并没有操作返回值r,因此,main函数中调用f()得到5。QYp28资讯网——每日最新资讯28at.com

图片图片QYp28资讯网——每日最新资讯28at.com

第二个例子:

func f()(r int){  defer func(r int){    r=r+5    }(r)        return 1}

拆解后:QYp28资讯网——每日最新资讯28at.com

func f() (r int) {  //1.赋值   r=1    //2.这里改的r是之前传进去的r,不会改变要返回的那个r值   func(r int) {    r=r+5  }(r)    // 3. 空的 return   return}

第二步,改变的是传值进去的r,是形参的一个复制值,不会影响实参r。因此,main函数中需要调用f()得到1。QYp28资讯网——每日最新资讯28at.com

图片图片QYp28资讯网——每日最新资讯28at.com


QYp28资讯网——每日最新资讯28at.com

在使用匿名函数和非匿名函数作为defer的参数时,主要区别在于对函数参数的传递和作用域的影响:QYp28资讯网——每日最新资讯28at.com

  1. 匿名函数作为defer的参数:匿名函数可以直接在defer语句中定义,可以访问外部函数的变量,并且在执行时会使用当前的变量值。这种方式可以方便地在defer语句中使用外部变量,但需要注意变量的值在执行时可能已经发生了改变。
  2. 非匿名函数作为defer的参数:非匿名函数需要先定义好,然后作为defer的参数传递。在执行时,会使用函数的当前参数值。这种方式可以在defer语句中使用已定义的函数,但需要注意函数参数的传递和作用域。

产生这种区别的原因是,匿名函数和非匿名函数在定义和作用域上的差异。匿名函数可以直接在defer语句中定义,可以访问外部函数的变量,而非匿名函数需要先定义好,然后作为参数传递。这种设计灵活性使得开发者可以根据具体的需求选择合适的方式来使用defer语句。QYp28资讯网——每日最新资讯28at.com

举例来说

当使用匿名函数作为defer的参数时,可以在defer语句中直接定义匿名函数,并访问外部变量。QYp28资讯网——每日最新资讯28at.com

以下是一个示例代码:QYp28资讯网——每日最新资讯28at.com

package mainimport "fmt"func main() {    x := 10    defer func() {        fmt.Println("Deferred anonymous function:", x)    }()    x = 20    fmt.Println("Before return:", x)}

在上述示例中,匿名函数作为defer的参数,可以访问外部变量x。在函数返回之前,defer语句中的匿名函数会执行,并打印出x的值。QYp28资讯网——每日最新资讯28at.com

输出结果如下:QYp28资讯网——每日最新资讯28at.com

图片图片QYp28资讯网——每日最新资讯28at.com

当使用非匿名函数作为defer的参数时,需要先定义好函数,然后将函数名作为defer的参数传递。QYp28资讯网——每日最新资讯28at.com

以下是一个示例代码:QYp28资讯网——每日最新资讯28at.com

package mainimport "fmt"func main() {    x := 10    defer printX(x)    x = 20    fmt.Println("Before return:", x)}func printX(x int) {    fmt.Println("Deferred function:", x)}

在上述示例中,printX函数作为defer的参数传递,函数定义在main函数之后。QYp28资讯网——每日最新资讯28at.com

在函数返回之前,defer语句中的printX函数会执行,并打印出传递的参数x的值。输出结果如下:QYp28资讯网——每日最新资讯28at.com

图片图片QYp28资讯网——每日最新资讯28at.com

总结一下

通过以上示例,我们可以明确体现出使用匿名函数和非匿名函数作为defer的参数的区别。QYp28资讯网——每日最新资讯28at.com

匿名函数可以直接在defer语句中定义,并访问外部变量,而非匿名函数需要先定义好函数,然后将函数名作为参数传递。QYp28资讯网——每日最新资讯28at.com

通过前面带着大家拆解了defer的语句的执行,相信大家可以更好的理解了。QYp28资讯网——每日最新资讯28at.com

本文转载自微信公众号「 程序员升级打怪之旅」,作者「  王中阳Go」,可以通过以下二维码关注。QYp28资讯网——每日最新资讯28at.com

QYp28资讯网——每日最新资讯28at.com

转载本文请联系「 程序员升级打怪之旅」公众号。QYp28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-30059-0.html解密defer语句:避免踩坑,掌握延迟执行的正确姿势

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Angular怎么还没死

下一篇: 领克 04 全地形越野自行车发布:喜德盛开发、X6 铝合金车架,售 3299 元

标签:
  • 热门焦点
  • 小米官宣:2023年上半年出货量中国第一!

    今日早间,小米电视官方微博带来消息,称2023年小米电视上半年出货量达到了中国第一,同时还表示小米电视的巨屏风暴即将开始。“公布一个好消息2023年#小米电视上半年出货量中国
  • Redmi Pad评测:红米充满野心的一次尝试

    从Note系列到K系列,从蓝牙耳机到笔记本电脑,红米不知不觉之间也已经形成了自己颇有竞争力的产品体系,在中端和次旗舰市场上甚至要比小米新机的表现来得更好,正所谓“大丈夫生居
  • 虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • 每天一道面试题-CPU伪共享

    前言:了不起:又到了每天一到面试题的时候了!学弟,最近学习的怎么样啊 了不起学弟:最近学习的还不错,每天都在学习,每天都在进步! 了不起:那你最近学习的什么呢? 了不起学弟:最近在学习C
  • 东方甄选单飞:有些鸟注定是关不住的

    文/彭宽鸿编辑/罗卿东方甄选创始人俞敏洪带队的“7天甘肃行”直播活动已在近日顺利收官。成立后一年多时间里,东方甄选要脱离抖音自立门户的传闻不绝于耳,“7
  • OPPO、vivo、小米等国内厂商Q2在印度智能手机市场份额依旧高达55%

    7月20日消息,据外媒报道,研究机构的报告显示,在全球智能手机出货量同比仍在下滑的大背景下,印度这一有潜力的市场也未能幸免,出货量同比也有下滑,多家厂
  • 国行版三星Galaxy Z Fold5/Z Flip5发布 售价7499元起

    2023年8月3日,三星电子举行Galaxy新品中国发布会,正式在国内推出了新一代折叠屏智能手机三星Galaxy Z Fold5与Galaxy Z Flip5,以及三星Galaxy Tab S9
  • iQOO Neo8系列或定档5月23日:首发天玑9200+ 安卓跑分王者

    去年10月,iQOO推出了iQOO Neo7系列机型,不仅搭载了天玑9000+,而且是同价位唯一一款天玑9000+直屏旗舰,一经上市便受到了用户的广泛关注。在时隔半年后,
  • 英特尔Xe HPG游戏显卡:拥有512EU,单风扇版本

    据10 月 30 日外媒 TheVerge 消息报道,英特尔 Xe HPG Arc Alchemist 的正面实被曝光,不仅拥有 512 EU 版显卡,还拥有 128EU 的单风扇版本。另外,这款显卡 PCB
Top