golang defer执行顺序全面详解
更新时间:2023年09月27日 11:19:09 作者:werbenhu
这篇文章主要为大家介绍了golang defer执行顺序全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
defer的执行顺序
多个defer是一个栈
的结构,是先进后出,下面这个代码的输出顺序是CBA。
package main import "fmt" func main() { defer func1() defer func2() defer func3() } func func1() { fmt.Println("A") } func func2() { fmt.Println("B") } func func3() { fmt.Println("C") }
defer和return的顺序
先执行return,再执行defer。
package main import "fmt" func deferFunc() { fmt.Println("defer func called") } func returnFunc() int { fmt.Println("return func called") return 0 } func returnAndDefer() int { defer deferFunc() return returnFunc() } func main() { returnAndDefer() } // output: // return func called // defer func called
函数命名返回值遇见defer
package main import "fmt" func foo() (t int) { defer func() { t = t * 10 }() return 1 } func main() { fmt.Println(foo()) } // output: 10
defer和panic
panic阻断defer
import ( "fmt" ) func deferFn() { defer func() { fmt.Println("defer before panic 1") }() defer func() { fmt.Println("defer before panic 2") }() panic("exit") defer func() { fmt.Println("defer after panic") }() } func main() { deferFn() fmt.Println("main exit") } /* output: defer before panic 2 defer before panic 1 panic: exit ... */
defer里面的recover
defer在panic 后依然有效
package main import ( "fmt" ) func deferFn() { defer func() { fmt.Println("defer before panic 1") if err := recover(); err != nil { fmt.Println(err) } }() defer func() { fmt.Println("defer before panic 2") }() panic("panic info") defer func() { fmt.Println("defer after panic") }() } func main() { deferFn() fmt.Println("main exit") } /* output: defer before panic 2 defer before panic 1 panic info main exit */
defer中包含panic
panic仅有最后一个可以被revover捕获
package main import ( "fmt" ) func main() { defer func() { if err := recover(); err != nil { fmt.Println(err) } else { fmt.Println("defer call") } }() defer func() { panic("defer panic") }() panic("main panic") } // output: defer panic
defer中函数有参数和包含子函数
package main import "fmt" func foo(index int, value int) int { fmt.Println(index) return index } func main() { defer foo(1, foo(3, 0)) defer foo(2, foo(4, 0)) } // output: 3 4 2 1
测试练习
package main import "fmt" func DeferFunc1(i int) (t int) { t = i defer func() { t += 3 }() return t } func DeferFunc2(i int) int { t := i defer func() { t += 3 }() return t } func DeferFunc3(i int) (t int) { defer func() { t += i }() return 2 } func DeferFunc4() (t int) { defer func(i int) { fmt.Println(i) fmt.Println(t) }(t) t = 1 return 2 } func main() { fmt.Println(DeferFunc1(1)) fmt.Println(DeferFunc2(1)) fmt.Println(DeferFunc3(1)) DeferFunc4() }
以上就是golang defer执行顺序全面详解的详细内容,更多关于golang defer执行顺序的资料请关注脚本之家其它相关文章!
相关文章
Go在GoLand中引用github.com中的第三方包具体步骤
这篇文章主要给大家介绍了关于Go在GoLand中引用github.com中第三方包的具体步骤,文中通过图文介绍的非常详细,对大家学习或者使用Go具有一定的参考价值,需要的朋友可以参考下2024-01-01详解Golang net/http包中的RoundTripper接口
RoundTripper 是 net/http 包中的一个接口,定义了处理 HTTP 请求返回和响应的方法,是 http.Client 结构体中执行 http 请求的核心部分,本文将详细的给大家介绍Golang RoundTripper接口,需要的朋友可以参考下2023-09-09Go prometheus metrics条目自动回收与清理方法
这篇文章主要为大家介绍了Go prometheus metrics条目自动回收与清理方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-11-11
最新评论