package main func main() { defer print(123) defer_call() defer print(789) //panic之后的代码不会被执行 print("不会执行到这里") } func defer_call() { defer func() { print("打印前") }() defer func() { print("打印中") }() defer print("打印后") panic("触发异常") defer print(666) //IDE会有提示: Unreachable code }
结果为:
打印后打印中打印前123panic: 触发异常 goroutine 1 [running]: main.defer_call() /Users/shuangcui/explore/panicandrecover.go:19 +0xe5 main.main() /Users/shuangcui/explore/panicandrecover.go:6 +0x51
可见:
(defer机制底层,是用链表实现的一个栈)
再如:
func main() { fmt.Println(123) defer fmt.Println(999) subfunc() } func subfunc() { defer fmt.Println(888) for i := 0; i > 10; i++ { fmt.Println("当前i为:", i) panic("have a bug") } defer fmt.Println(456) }
结果为:
123 456 888 999
defer会延迟到当前函数执行 return 命令前被执行, 多个defer之间按LIFO先进后出顺序执行
package main import "fmt" func main() { foo() } func foo() { i := 0 defer func() { //i-- fmt.Println("第一个defer", i) }() i++ fmt.Println("+1后的i:", i) defer func() { //i-- fmt.Println("第二个defer", i) }() i++ fmt.Println("再+1后的i:", i) defer func() { //i-- fmt.Println("第三个defer", i) }() i++ fmt.Println("再再+1后的i:", i) i = i + 666 fmt.Println("+666后的i为:", i) }
输出为:
+1后的i: 1 再+1后的i: 2 再再+1后的i: 3 +666后的i为: 669 第三个defer 669 第二个defer 669 第一个defer 669
package main import "fmt" func main() { foo() } func foo() { i := 0 defer func() { i-- fmt.Println("第一个defer", i) }() i++ fmt.Println("+1后的i:", i) defer func() { i-- fmt.Println("第二个defer", i) }() i++ fmt.Println("再+1后的i:", i) defer func() { i-- fmt.Println("第三个defer", i) }() i++ fmt.Println("再再+1后的i:", i) i = i + 666 fmt.Println("+666后的i为:", i) }
输出为:
+1后的i: 1 再+1后的i: 2 再再+1后的i: 3 +666后的i为: 669 第三个defer 668 第二个defer 667 第一个defer 666
---
传递参数给defer后面的函数, defer内外同时操作该参数)package main import "fmt" func main() { foo2() } func foo2() { i := 0 defer func(k int) { //k-- fmt.Println("第一个defer", k) }(i) i++ fmt.Println("+1后的i:", i) defer func(k int) { //k-- fmt.Println("第二个defer", k) }(i) i++ fmt.Println("再+1后的i:", i) defer func(k int) { //k-- fmt.Println("第三个defer", k) }(i) i++ fmt.Println("再再+1后的i:", i) i = i + 666 fmt.Println("+666后的i为:", i) }
输出为:
+1后的i: 1 再+1后的i: 2 再再+1后的i: 3 +666后的i为: 669 第三个defer 2 第二个defer 1 第一个defer 0
如果取消三处k--
的注释, 输出为:
+1后的i: 1 再+1后的i: 2 再再+1后的i: 3 +666后的i为: 669 第三个defer 1 第二个defer 0 第一个defer -1
等同于:
package main import "fmt" func main() { foo3() } func foo3() { i := 0 defer f1(i) i++ fmt.Println("+1后的i:", i) defer f2(i) i++ fmt.Println("再+1后的i:", i) defer f3(i) i++ fmt.Println("再再+1后的i:", i) i = i + 666 fmt.Println("+666后的i为:", i) } func f1(k int) { k-- fmt.Println("第一个defer", k) } func f2(k int) { k-- fmt.Println("第二个defer", k) } func f3(k int) { k-- fmt.Println("第三个defer", k) }
defer指定的函数的参数在 defer 时确定,更深层次的原因是Go语言都是值传递。
---
传递参数给defer后面的函数, defer内外同时操作该参数)package main import "fmt" func main() { foo5() } func foo5() { i := 0 defer func(k *int) { fmt.Println("第一个defer", *k) }(&i) i++ fmt.Println("+1后的i:", i) defer func(k *int) { fmt.Println("第二个defer", *k) }(&i) i++ fmt.Println("再+1后的i:", i) defer func(k *int) { fmt.Println("第三个defer", *k) }(&i) i++ fmt.Println("再再+1后的i:", i) i = i + 666 fmt.Println("+666后的i为:", i) }
输出为:
+1后的i: 1 再+1后的i: 2 再再+1后的i: 3 +666后的i为: 669 第三个defer 669 第二个defer 669 第一个defer 669
作如下修改:
package main import "fmt" func main() { foo5() } func foo5() { i := 0 defer func(k *int) { (*k)-- fmt.Println("第一个defer", *k) }(&i) i++ fmt.Println("+1后的i:", i) defer func(k *int) { (*k)-- fmt.Println("第二个defer", *k) }(&i) i++ fmt.Println("再+1后的i:", i) defer func(k *int) { (*k)-- fmt.Println("第三个defer", *k) }(&i) i++ fmt.Println("再再+1后的i:", i) i = i + 666 fmt.Println("+666后的i为:", i) }
输出为:
+1后的i: 1 再+1后的i: 2 再再+1后的i: 3 +666后的i为: 669 第三个defer 668 第二个defer 667 第一个defer 666
Copyright © 2023 leiyu.cn. All Rights Reserved. 磊宇云计算 版权所有 许可证编号:B1-20233142/B2-20230630 山东磊宇云计算有限公司 鲁ICP备2020045424号
磊宇云计算致力于以最 “绿色节能” 的方式,让每一位上云的客户成为全球绿色节能和降低碳排放的贡献者