iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >golang中的defer函数怎么用
  • 361
分享到

golang中的defer函数怎么用

2023-07-04 11:07:42 361人浏览 八月长安
摘要

本文小编为大家详细介绍“golang中的defer函数怎么用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Golang中的defer函数怎么用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。golang的defe

本文小编为大家详细介绍“golang中的defer函数怎么用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Golang中的defer函数怎么用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    golang的defer

    什么是defer

    go语言中defer可以完成延迟功能,当前函数执行完成后再执行defer的代码块。通过defer,我们可以在代码中优雅的关闭/清理代码中所使用的变量。

    defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源、关闭数据库连接、断开Socket连接、解一个加锁的资源。

    Go语言机制担保一定会执行defer语句中的代码。其它语言中也有类似的机制,比如Java、C#语言里的finally语句,c++语言里的析构函数(Destructor)可以起类似的作用,C++语言机制担保在对象被销毁前一定会执行析构函数中的代码。C++中的析构函数析构的是对象,Go中的defer析构的是函数。

    理解defer

    defer什么时间执行(defer、 return、返回值 三者的执行顺序)

    defer只有在当前函数执行完毕后,才会执行。描述其实不太精确

    go中的return语句并不是原子性操作,一般是分为两步:

    • 将返回值赋值给一个变量

    • 执行RET指令

    return并不是原子性操作,是通过一个变量赋值和ret指令来完成的。defer就执行在1之后,2之前。defer的执行顺序在return之后,但是在返回值返回给调用方之前,所以使用defer可以达到修改返回值的目的。

    defer、 return、返回值 三者的执行顺序是 : return 最先给返回值赋值;接着 defer 开始执行一些收尾工作;最后 RET 指令携带返回值退出函数。

    package mainimport (    "fmt")func main() {    ret := test()    fmt.Println("test return:", ret)}// func test() ( int) {  这种就是匿名返回值//返回值改为命名返回值, 具名返回值。即返回值带有名字, 这样我们在执行defer的时候相当于修改了返回值的值func test() (i int) {    //var i int    defer func() {        i++        fmt.Println("test defer, i = ", i)    }()    return i}

    注意: 这块验证使用了具名返回值 func test() (i int) { 中的(i int)测试结果满足我们预期。

    编码中,我们要特别注意, go语言中匿名返回值和命名返回值对defer的影响。不过一般我们都是使用命名返回值。

    一个主函数拥有一个匿名的返回值,返回时使用字面值,比如返回”1”、”2”、”Hello”这样的值,这种情况下defer语句是无法操作返回值的。

    defer输出的值,就是定义时的值。而不是defer真正执行时的变量值(注意引用情况)

    defer函数会在return之后被调用。那么这段函数执行完之后,是不用应该输出1呢?

    package mainimport "fmt"func test1() {i := 0defer fmt.Println(i)i++return}func main() {test1()}

    输出结果:0

    虽然我们在defer后面定义的是一个带变量的函数: fmt.Println(i). 但这个变量(i)在defer被声明的时候,就已经确定其确定的值了。

    总结: 因为defer后面的函数在入栈的时候保存的是入栈那一刻的值,而当时i的值是0,所以后期对i修改,并不会影响栈内函数的值。

    我们再看下一个例子:

    package mainimport "fmt"func test2() {x := 10defer func(a *int) {fmt.Println(*a)}(&x)x++}func main() {test2()}

    输出结果: 11

    这里为什么和前面结论不一样呢?
    这里defer后面函数入栈的时候存入的执行变量x的指针。所以,后期x值改变的时候,输出结果也会改变。

    总结: 需要注意引用情况。对于指针类型参数,规则仍然适用,只不过延迟函数的参数是一个地址值,这种情况下,defer后面的语句对变量的修改会影响延迟函数。

    多个defer,执行顺序
    package mainimport (    "fmt")func main() {    defer fmt.Println("main defer1")    test()    defer fmt.Println("main defer2")}func test() () {    defer func() {        fmt.Println("test defer1")    }()    defer func() {        fmt.Println("test defer2")    }()}

    输出结果:

    test defer2
    test defer1
    main defer2
    main defer1

    总结: 后进先出(LIFO)的顺序执行,即先出现的 defer 最后执行。即:多个defer语句的执行顺序是逆序执行。

    defer的函数一定会执行么?

    defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源、关闭数据库连接、断开socket连接、解锁一个加锁的资源。

    Go语言机制担保一定会执行defer语句中的代码。其它语言中也有类似的机制,比如Java、C#语言里的finally语句,C++语言里的析构函数(Destructor)可以起类似的作用,C++语言机制担保在对象被销毁前一定会执行析构函数中的代码。C++中的析构函数析构的是对象,Go中的defer析构的是函数。

    panic情况

    网上demo:

    package mainimport ("fmt")func test1() {fmt.Println("test")}func test2() {panic(1)}func main() {fmt.Println("main start")defer test1()test2() //造panicfmt.Println("main end")}

    执行结果:

    main start
    test                                                                  
    panic: 1                                                                                                                                   
    goroutine 1 [running]:                                                
    main.test2(...)         

    总结: 我们发现正常的panic,还是会调我们的defer的,并且在会在panic之前执行。

    os.Exit情况

    网上demo:

    package mainimport ("fmt""os")func test1() {fmt.Println("test")}func main() {fmt.Println("main start")defer test1()fmt.Println("main end")os.Exit(0)}

    执行结果:

    main start
    main end

    总结: 如果在当前函数里是因为执行了os.Exit退出,而不是正常return退出或者panic退出,那程序会立即停止,被defer的函数调用不会执行。

    kill情况(Ctrl+C)
    package mainimport ("fmt""time")func test1() {fmt.Println("test")}func test2() {time.Sleep(60 * time.Second)}func main() {fmt.Println("main start")defer test1()test2()fmt.Println("main end")}

    执行结果:

    main start

    Process finished with the exit code -1073741510 (0xC000013A: interrupted by Ctrl+C)

    如上,我们test2() 睡眠时间内,点击Ctrl+C,发现defer test1()并没有执行。

    总结:这个点很重要,需要我们在日常异常中断时,留意defer是否未处理的情况。
    所以一般情况下,我们程序需要捕获这种异常中断,在程序退出前,手动做一些处理。

    读到这里,这篇“golang中的defer函数怎么用”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网GO频道。

    您可能感兴趣的文档:

    --结束END--

    本文标题: golang中的defer函数怎么用

    本文链接: https://www.lsjlt.com/news/344533.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • golang中的defer函数怎么用
      本文小编为大家详细介绍“golang中的defer函数怎么用”,内容详细,步骤清晰,细节处理妥当,希望这篇“golang中的defer函数怎么用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。golang的defe...
      99+
      2023-07-04
    • golang中的defer函数理解
      目录golang的defer什么是defer理解deferdefer什么时间执行(defer、 return、返回值 三者的执行顺序)defer输出的值,就是定义时的值。而不是def...
      99+
      2024-04-02
    • golang函数的defer和panic
      defer 和 panic 关键字用于控制异常和后置处理:defer:将函数压入栈,在函数返回后执行,常用于释放资源。panic:抛出异常,中断程序执行,用于处理无法继续运行的严重错误。...
      99+
      2024-04-20
      defer panic golang
    • golang中defer怎么使用
      这篇文章主要介绍“golang中defer怎么使用”,在日常操作中,相信很多人在golang中defer怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”golang中defer怎么使用”的疑惑有所帮助!...
      99+
      2023-07-02
    • Golang函数的defer语句在文件关闭中怎么使用
      这篇文章主要介绍了Golang函数的defer语句在文件关闭中怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang函数的defer语句在文件关闭中怎么使用文章都会有所收获,下面我们一起来看看吧。G...
      99+
      2023-07-06
    • Golang函数的defer语句使用解析
      Golang是一种面向对象、并发支持、编译成机器码的编程语言,具备简洁的语法、高效的性能和丰富的标准库。在Golang中,使用defer语句对某个函数进行延迟执行,这种语言特性在编写代码时非常有用。本文将阐述Golang函数的defer语句...
      99+
      2023-05-16
      函数 Golang defer语句
    • Golang中defer预计算参数怎么用
      小编给大家分享一下Golang中defer预计算参数怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!什么是deferdefer用来声明一个延迟函数,把这个函数放入到一个栈上, 当外部的包含方法return之前,返回参数...
      99+
      2023-06-29
    • Golang中的defer关键字怎么使用
      在Golang中,defer关键字用于注册一个函数调用,该函数会在当前函数执行完成后被执行,无论函数是正常返回还是发生了panic。...
      99+
      2024-03-13
      Golang
    • Golang函数的defer关键字的多种用法
      Golang是一种非常流行的编程语言,其语言特性非常丰富,其中之一就是使用defer关键字来完成一些特定的功能。在本文中,我们将会介绍多种使用defer关键字的方式。延迟函数的执行在Golang中,defer关键字最常用的功能就是延迟函数的...
      99+
      2023-05-17
      函数 Golang defer
    • Golang函数的defer语句在文件关闭中的用法
      Golang是一种被广泛应用于Web开发的编程语言,其提供了多种强大的数据类型和语言特性,使得在项目开发中可以更加高效地进行编码。其中一个非常实用的特性就是defer语句,用于在函数返回前执行一段代码。在本文中,我们将讨论如何利用Golan...
      99+
      2023-05-16
      Golang defer 文件关闭
    • Golang函数的defer关键字在异常处理中的应用
      Golang是一门现代化的编程语言,其简洁、高效的设计风格备受开发者的推崇。在Golang中,函数的defer关键字是一个非常有用的特性,它可以帮助我们在函数返回前进行一些资源的清理工作。不仅如此,defer还可以在异常处理中发挥巨大的作用...
      99+
      2023-05-16
      函数 Golang defer关键字
    • 详解golang defer 闭包 匿名函数
      目录defer的触发时机defer,return,返回值的执行顺序闭包与匿名函数defer用于资源的释放,会在函数返回之前进行调用。如果有多个defer表达式,调用顺序类似于栈,越后...
      99+
      2024-04-02
    • golang中defer的基本使用教程
      目录前言1.什么是defer2.defer的特点3.defer什么时间执行4.defer常见的坑1.输出是多少?2.输出多少3.输出多少4.输出什么总结前言 第一次看go基础语法的时...
      99+
      2024-04-02
    • GO语言延迟函数defer怎么使用
      今天小编给大家分享一下GO语言延迟函数defer怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。go语言中defer最...
      99+
      2023-07-05
    • Golang函数的defer关键字的异常处理方法
      Golang是一种相对新兴、开源且具有高性能的编程语言,它的特点之一就是函数的defer关键字。这个关键字可以让我们在函数结束前执行一些需要操作,如资源清理、日志输出等,同时也可以用来处理异常情况,使我们的代码具有更好的健壮性和可靠性。本文...
      99+
      2023-05-17
      Golang 函数 defer关键字。
    • Golang中的init ()函数怎么使用
      本文小编为大家详细介绍“Golang中的init ()函数怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Golang中的init ()函数怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Go in...
      99+
      2023-07-04
    • GoLang中panic与recover函数以及defer语句超详细讲解
      目录一、运行时恐慌panic二、panic被引发到程序终止经历的过程三、有意引发一个panic并让panic包含一个值四、施加应对panic的保护措施从而避免程序崩溃五、多条defe...
      99+
      2023-01-11
      Go panic函数 Go recover函数 Go defer语句
    • 详解golang中的闭包与defer
      目录闭包与defer1.闭包2.defer闭包与defer 1.闭包 闭包 : 一个函数与其相关的引用环境组合的一个实体,其实可以理解为面向对象中类中的属性与方法。如代码块中,函数f...
      99+
      2024-04-02
    • Golang中关于defer的盲区梳理
      目录defer的执行顺序是什么样的defer与return谁先谁后函数的返回值初始化与defer间接影响defer遇见panic。defer中包含panicdefer下的函数参数包含...
      99+
      2023-03-06
      Golang defer盲区 Golang defer Go defer
    • 简单聊聊Golang中defer预计算参数
      目录什么是deferGo语言defer预计算参数总结什么是defer defer用来声明一个延迟函数,把这个函数放入到一个栈上, 当外部的包含方法return之前,返回参数到调用方法...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作