GO 中的 defer 有哪些注意事项?上

简介: GO 中的 defer 有哪些注意事项?上

xdm , 不知道你们是否有使用过 defer ,这种语法在是 go 特有的,用起来真是爽的不要不要的

很多时候,我们在使用一些新东西,出现一些莫名其妙的现象或者是结果的时候,我们总会认为,这个东西不友好, 这个东西好坑,好奇怪

其实我们是要弄明白其中的注意点,原理,当出现所谓的奇怪现象的时候,处理起来就会得心应手得多

xdm,这里准备了如下注意事项,请查收

案例 1

这里先统一说明一下 defer 是干什么的?

是 GO 中的一个关键字

这个关键字,我们一般用在释放资源,在 return 前会调用他

如果程序中有多个 defer ,defer 的调用顺序是按照类似的方式,后进先出 LIFO的 , 具体的 defer 实现原理可以查看我的历史文章 GO 中 defer的实现原理

先来看一个 demo,猜一猜他的输出是什么?

写一个 defer 和 defer 在一起的 输入输出顺序 demo

  • 简单写 4 个函数,分别应用到 defer 上
func test1() {
  fmt.Println("test 1")
}
func test2() {
  fmt.Println("test 2")
}
func test3() {
  fmt.Println("test 3")
}
func test4() {
  fmt.Println("test 4")
}
func main() {
  defer test1()
  defer test2()
  defer test3()
  defer test4()
}

运行上述代码,我们期望的结果是什么呢?

test 1
test 2
test 3
test 4

还是

test 4
test 3
test 2
test 1

小伙伴们感兴趣的可以运行一下,结果是 第二种,defer 我们可以理解为是一个入栈操作,先进后出

入栈 : test1(),test2(),test3(),test4()

出栈 : test4(),test3(),test2(),test1()

案例 2

上面我们知道 defer 和 defer 的顺序是按照栈的顺序来,那么我们下面来看看 defer 和 return 的顺序又是什么样子的 ?

  • 简单写 一个用于 return 的函数和 用于 defer 的函数
func testDefer() {
  fmt.Println("testDefer")
}
func testReturn() int {
  fmt.Println("testReturn")
  return 1
}
func myTest() int {
  defer testDefer()
  return testReturn()
}
func main() {
  myTest()
}

再来猜测一下上述编码会是如何执行的呢

是这样的吗?

testDefer
testReturn

还是这样的 ?

testReturn
testDefer

结果仍然是第二种,通过上述编码我们可以看出来 defer 后面的语句 是晚执行的, return 后面的语句是先执行的

那么如果是 多个 defer 和 return 放在一起呢?

xdm ,咱们举一反三了,那肯定还是 return 先执行,defer 按照栈的顺序执行

案例 3

这个案例咱们加上简单的计算,看看效果如何

  • 简单些一下带有计算的 defer
func testDefer(num int)(res int){
  defer func(){
    res = num + 3
  }()
  return num
}
func main(){
  res := testDefer(5)
  fmt.Println(res)
}

上述编码运行后会是什么效果呢

是 5 吗? 是 8 吗?反正肯定不是 3 吧

思考一下,按照上面案例 1 的逻辑,结果是 8

老铁,没毛病, num 通过 testDefer 函数传值,赋值 为 5 ,return num 的时候,返回值是 5,再执行 defer 语句, 5+3 就是 8

好了,今天就到这里,感兴趣的朋友也可以玩起来

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

相关文章
|
6月前
|
Go
Go语言中defer的执行顺序详解
【2月更文挑战第22天】
108 4
|
3月前
|
存储 Go
掌握 Go 语言的 defer 关键字
掌握 Go 语言的 defer 关键字
|
3月前
|
Go
实验深度理解Go中try...catch...的panic、defer、recover用法
文章通过实验代码演示了Go语言中如何使用panic、defer和recover函数来模拟try...catch...的异常处理机制,并详细解释了每个函数的作用和在异常处理中的使用场景。
35 0
|
5月前
|
程序员 编译器 Go
常见的go语言十大注意事项
【6月更文挑战第18天】本文记录 Go语言常见问题概览,包括运行风险, 空值对比 ,级数计算,Channel使用,结构体嵌套检测,面向对象限制,for循环陷阱,ABI调用,可变参数,数组传递,map遍历,返回值屏蔽 ,recover用法,Goroutine管理,CPU独占,并发一致性,闭包引用,循环defer,切片内存管理
88 3
常见的go语言十大注意事项
|
5月前
|
Go 调度
使用go语言的其他注意事项
【6月更文挑战第19天】本文汇总记录了在使用go语言时需要注意的一些技巧,比如数组,map,goroutine,defer等使用事项。
128 4
|
6月前
|
Go 开发者
Golang深入浅出之-Go语言 defer、panic、recover:异常处理机制
Go语言中的`defer`、`panic`和`recover`提供了一套独特的异常处理方式。`defer`用于延迟函数调用,在返回前执行,常用于资源释放。它遵循后进先出原则。`panic`触发运行时错误,中断函数执行,直到遇到`recover`或程序结束。`recover`在`defer`中捕获`panic`,恢复程序执行。注意避免滥用`defer`影响性能,不应对可处理错误随意使用`panic`,且`recover`不能跨goroutine捕获panic。理解并恰当使用这些机制能提高代码健壮性和稳定性。
132 2
|
6月前
|
Java Go 区块链
【Go语言专栏】Go语言中的延迟执行与defer语句
【4月更文挑战第30天】Go语言的延迟执行与defer语句用于资源释放和错误处理。defer通过关键字定义,函数返回时执行,顺序与定义相反。参数在定义时求值。应用包括资源释放、错误处理、成对操作和函数包装,是Go编程的关键特性。
55 0
|
6月前
|
存储 缓存 安全
掌握Go语言:Go语言Map,高效键值对集合的应用与注意事项详解(26)
掌握Go语言:Go语言Map,高效键值对集合的应用与注意事项详解(26)
|
6月前
|
网络协议 BI Go
Go-异常处理(defer recover panic)
Go-异常处理(defer recover panic)
76 0
|
6月前
|
存储 Go
Go 语言之 Maps 详解:创建、遍历、操作和注意事项
Maps用于以键值对的形式存储数据值。Maps中的每个元素都是一个键值对。Maps是一个无序且可更改的集合,不允许重复。Maps的长度是其元素的数量。您可以使用 len() 函数来查找长度。Maps的默认值是 nil。Maps保存对底层哈希表的引用。
80 0