【Go面试向】defer与return的执行顺序初探

这篇具有很好参考价值的文章主要介绍了【Go面试向】defer与return的执行顺序初探。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

defer与return常考点

简述 defer 和 return 返回值 的执行顺序?如果要返回一个 defer 执行后的值, 可以通过哪些方式?

大家好 我是寸铁👊
总结了一篇defer 和 return 返回值 的执行顺序探讨的文章✨
喜欢的小伙伴可以点点关注 💝

程序1

不返回具体变量

执行顺序:
进入test函数

  1. 先把返回的结果赋值
  2. 执行defer函数
  3. 如果说defer函数中存在打印输出的内容,则先输出defer语句的内容。
    按照指定的顺序输出,后进先出的顺序输出
  4. 再返回到主函数main中,把之前赋值的返回的结果输出来

注意:return的结果是不会受defer函数而影响的,但是假如在defer外return之前进行赋值
则会返回当前更新的值。

demo


func Test() int {
    a := 1
    defer func() {
        fmt.Println("a", a) // a 1 
        a = 4
        fmt.Println("2", a) // 2 4
    }()
    return a // 1
}
func main() {
    fmt.Println(Test()) //1

}

程序2

返回指定的变量

执行顺序:
进入test函数

  1. 先把返回的结果赋值
  2. 执行defer函数
  3. 如果说defer函数中存在打印输出的内容,则先输出defer函数语句的内容。
    按照指定的顺序输出,后进先出的顺序输出
  4. 再返回到主函数main中,把之前赋值的返回的结果输出来

注意:函数中先对返回的结果进行定义:= 而不是直接赋值=,return的结果是不会受defer函数而影响的,但是假如在defer外 return之前进行赋值 则会返回当前更新的值。如下demo1和demo2


函数内先对返回值定义:=

demo1



func f() (r int) {
    t := 5
    defer func() {
        t = t + 5
    }()
    return t
}
func main() {
    fmt.Println(f())//5
}

验证一下return的结果会不会受到defer函数的影响
根据输出结果,是不会受到影响的!

demo2

func f() (r int) {
    t := 5
    defer func() {
        t = t + 5
        t = 12
    }()
    t = 20
    return t //此时t从5 --> 20
}
func main() {
    fmt.Println(f())//20
}


再来看这种情况,与上面的demo不同的点在于返回参数result在defer中参与了运算

demo3

func deferFuncReturn() (result int) {
    i := 5
    defer func() {
       result += 5
    }()
    return i //这里由于返回的result参与了运算,所以会经过defer处理,返回的结果为10
}

函数说明:

函数拥有一个具名返回值result,函数内部声明一个变量idefer指定一个延迟函数,最后返回变量i。延迟函数中增加result

参考答案:

函数输出10。函数的return语句并不是原子的,实际执行分为设置返回值—>ret,defer语句实际执行在返回前,即拥有defer的函数返回过程是:设置返回值—>执行defer—>ret。所以return语句先把result设置为i的值,即5,defer语句中又把result递增5,所以最终返回10。

小结:
所以,这里的关键点在于具名返回值(也就是返回的参数列表中的变量)是否参与defer 运算,参与运算则返回值会受到defer的处理影响,不参与则与之无关。


函数内没有对返回值进行定义

函数中没有对返回值进行定义(:=) 函数返回值先进行初始化 之后在函数内进行赋值 之后defer函数可以返回经过defer操作后的值

返回值是与defer中的程序有关
demo

package main

import "fmt"

func f() (t int) {
    t = 5
    defer func() {
       t = t + 5
    }()
    return t //返回值是与defer中的程序有关 
}
func main() {
    fmt.Println(f())
}

分析:defer在return之后执行,但是在函数退出之前,defer可以修改返回值。这里是先对返回值赋值为5 之后待返回值赋值后 执行defer函数 对t的值进行修改 之后返回的值t也会被defer函数所修改。


再来看一下这一组demo

返回值是与defer中的程序有关 如果在defer的外面重新给t赋值后 则返回的结果值会随之修改

demo


package main

import "fmt"

func f() (t int) {
    t = 5
    defer func() {
       t = t + 5
    }()
    t  = 12
    return t //返回值是与defer中的程序有关 如果在defer的外面重新给t赋值后 则返回的结果值会随之修改
}
func main() {
    fmt.Println(f())//17
}

分析:这里先对返回值t进行赋值 此时t为5 此时还没执行defer函数 是在赋值给return 的结果完毕后才执行defer函数 很明显 这里t又被修改为12 此时t的值赋值完毕 开始执行defer函数,对t的值进行修改,此时t = 12 + 5 = 17 返回给主函数 输出17

返回一个defer执行后的值

如果要返回一个 defer 执行后的值, 可以通过那些方式?
见上:函数中没有对返回值进行定义的情况

简述:函数中没有对返回值进行定义(:=) 函数返回值先进行初始化 之后在函数内进行赋值 之后defer函数可以返回经过defer操作后的值


看到这里的小伙伴,恭喜你又掌握了一个知识点👊
后续有更新和变动,会在这里统一做更新,大家可以关注一波🙌
希望大家能取得胜利,坚持就是胜利💪
我是寸铁!我们下期再见💕文章来源地址https://www.toymoban.com/news/detail-808491.html

到了这里,关于【Go面试向】defer与return的执行顺序初探的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Golang】解决Go test执行单个测试文件提示未定义问题

    目录 背景 根本原因 解决方法 解决 多级引用或多个引用包的情况 总结  资料获取方法 很多人记录过怎么执行Go test单个文件或者单个函数,但是要么对执行单文件用例存在函数或变量引用的场景避而不谈,要么提示调用了其它文件中的模块会报错。其实了解了go test命令的机

    2024年02月14日
    浏览(40)
  • Go的Defer简介

    什么是延期? Defer 语句用于在存在 defer 语句的周围函数返回之前执行函数调用 。该定义可能看起来很复杂,但通过示例就很容易理解。 例子 Run in playground 上面是一个简单的程序,用于查找给定切片的最大数量。该 largest 函数接受一个int切片作为参数并打印该切片的最大数

    2024年02月06日
    浏览(37)
  • go语言(五)----defer

    1、defer的词义:“延迟”,“推迟” 在go语言中,defer来延迟一个函数或者方法的执行 1.defer函数或方法:一个函数或方法的执行被延迟了 2.defer的用法: A:对象.close(),临时文件的删除。。。 文件.open() defer close() 读或写 B:go语言中关于异常的处理,使用panic()和reco

    2024年01月20日
    浏览(38)
  • Go 自学:defer关键字

    我们可以使用defer延迟代码的执行,相当于我们把代码放入一个stack中,遵循last in first out的原则输出代码。 代码输出为: Hello 43210Two One World

    2024年02月10日
    浏览(70)
  • 【Go 基础篇】Go语言中的defer和recover:优雅处理错误

    Go语言以其简洁、高效和强大的特性受到了开发者的热烈欢迎。在错误处理方面,Go语言提供了一种优雅的机制,即通过 defer 和 recover 组合来处理恐慌(panic)错误。本文将详细介绍Go语言中的 defer 和 recover 机制,探讨其工作原理和在实际开发中的应用。 在软件开发过程中,

    2024年02月10日
    浏览(43)
  • Go for循环中的defer

    写个后台程序,定时抓取服务器指标,代码逻辑如下,使用一段时间后内存不断增加 一开始感觉是哪里文件或者网络忘记Close了,看下进程打开的文件. 如下图类似情况, 看到很多http ESTABLISHED状态,估计就是哪个http忘记Close. 排查代码,问题应该出现在上面一段代码,for循环中

    2024年02月09日
    浏览(31)
  • go语言基础 -- defer及其用法

    在go语言中,程序员创建的资源如文件句柄、数据库连接、锁等,需要在函数执行完毕后释放,因此go提供了defer的机制,在函数退出时去释放defer指定的资源,这样我们在一些资源申请的时候,可以先defer 声明释放语句,无需担心后续忘记释放资源。defer利用了栈,先声明的d

    2024年02月04日
    浏览(42)
  • Go 语言中 defer 使用时有哪些陷阱?

    大家好,我是 frank ,「 Golang 语言开发栈」公众号作者。 01 介绍 defer 的使用方式是在其后紧跟一个函数调用或方法调用,确保在其所在的函数体返回之前执行其调用的函数或方法。 在 Go 语言中,defer 一般用于资源释放,或使用 defer 调用一个匿名函数,在匿名函数中使用

    2024年01月21日
    浏览(35)
  • Go语言之函数补充defer语句,递归函数,章节练习

    defer语句是go语言提供的一种用于注册延迟调用的机制,是go语言中一种很有用的特性。 defer语句注册了一个函数调用,这个调用会延迟到defer语句所在的函数执行完毕后执行,所谓执行完毕是指该函数执行了return语句、函数体已执行完最后一条语句或函数所在协程发生了恐慌

    2024年02月17日
    浏览(50)
  • Go 函数的健壮性、panic异常处理、defer 机制

    1.1 原则一:不要相信任何外部输入的参数 函数的使用者可能是任何人,这些人在使用函数之前可能都没有阅读过任何手册或文档,他们会向函数传入你意想不到的参数。因此,为了保证函数的健壮性,函数需要对所有输入的参数进行合法性的检查。一旦发现问题,立即终止

    2024年02月07日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包