美文网首页
go语言defer的用法

go语言defer的用法

作者: 也许会了 | 来源:发表于2021-05-12 17:20 被阅读0次

用法介绍:

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

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

一、defer语句执行时机

defer语句在函数返回之前 或者 函数中 return语句(return语句可能调用另一个函数) 之后执行。示例代码:

package main

import (

"fmt"

)

func main() {

fmt.Println(deferReturn())

}

func deferReturn() (ret int) {

defer func() {

ret++

}()

return 10

}

上述代码打印出来的值是:11。 defer语句 匿名函数中的“ret++” 对返回值 10 加 1 变成了 11。再来看一个defer语句出现在return语句之后的代码:

func returnDefer() (ret int) {

return 0

defer func() {

ret++

ret++

}()

return 1

}

上述returnDefer函数的返回值是:0。原因是defer语句还没有添加上代码执行到"return 0"函数就返回了,因此defer语句就没有执行。

二、多个defer语句的执行顺序是逆序执行

当出现多条 defer 语句时以逆序执行(类似栈,即后进先出)。示例代码:

func deferSample() {

for i := 0; i < 5; i++ {

defer fmt.Printf("%d ", i)

}

}

上述代码将会输出:4 3 2 1 0

三、defer与panic

1、在panic语句后面的defer语句不被执行

示例代码:

func panicDefer() {

panic("panic")

defer fmt.Println("defer after panic")

}

上述代码的输出如下:

panic: panic

goroutine 1 [running]:

main.panicDefer()

E:/godemo/testdefer.go:17 +0x39

main.main()

E:/godemo/testdefer.go:13 +0x20

Process finished with exit code 2

可以看到 defer 语句没有执行。

2、在panic语句前的defer语句会被执行

示例代码:

func deferPanic() {

defer fmt.Println("defer before panic")

panic("panic")

}

上述代码的输出如下:

defer before panic

panic: panic

goroutine 1 [running]:

main.deferPanic()

E:/godemo/testdefer.go:19 +0x95

main.main()

E:/godemo/testdefer.go:14 +0x20

Process finished with exit code 2

defer 语句输出了内容。

Go中的panic类似其它语言中的抛出异常,panic后面的代码不再执行(panic语句前面的defer语句会被执行)。

四、return 的实现逻辑

1、第一步给返回值赋值(若是有名返回值直接赋值,匿名返回值 则 先声明再 赋值) ;

2、第二步调用RET返回指令并传入返回值,RET会检查是否存在defer语句,若存 在就先逆序插播 defer语句 ;

3、最后 RET 携带返回值退出函数 。

可以看出 , return 不是一个原子操作,函数返回值与 RET 返回值并不一定一致。

五、defer、 return、返回值三者顺序

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

本文来自php中文网的golang栏目:https://www.php.cn/be/go/

相关文章

  • go语言的defer语句

    go语言defer语句的用法 defer的语法 defer后面必须是函数调用语句,不能是其他语句,否则编译器会出错...

  • go语言defer的用法

    用法介绍: defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源、关闭数...

  • goLang异常处理

    defer defer是go提供的一种资源处理的方式。defer的用法遵循3个原则在defer表达式被运算的同时,...

  • Go语言基础(二)

    目录 关键字 defer go的defer用法范例[https://www.jianshu.com/p/7ada9...

  • go defer用法

    defer 通常用于 open/close, connect/disconnect, lock/unlock 等这...

  • GO中defer关键字

    defer关键字在go中用于return之前执行,在golang官方文档中有说明。defer的用法类似java中的...

  • Golang学习笔记-defer关键字学习

    defer学习 很多现代的变成语言中都会有defer关键字,Go语言的defer会在当前函数或是方法返回之前执行传...

  • Go语言学习进度(7)

    1.GO语言关键字Interface 举例说明: 2.GO语言关键字defer

  • Go语言 defer

    参考文章:深入理解Go语言 defer用于资源的释放,会在函数返回之前进行调用 defer关键字的实现跟go关键字...

  • Go语言——defer

    Go语言——defer defer操作类似stack,FILO先进后出。 与return一直使用的时候,需要注意顺...

网友评论

      本文标题:go语言defer的用法

      本文链接:https://www.haomeiwen.com/subject/lzgadltx.html