golang defer執(zhí)行順序全面詳解
defer的執(zhí)行順序
多個(gè)defer是一個(gè)棧的結(jié)構(gòu),是先進(jìn)后出,下面這個(gè)代碼的輸出順序是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的順序
先執(zhí)行return,再執(zhí)行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函數(shù)命名返回值遇見defer
package main
import "fmt"
func foo() (t int) {
defer func() {
t = t * 10
}()
return 1
}
func main() {
fmt.Println(foo())
}
// output: 10defer和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僅有最后一個(gè)可以被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 panicdefer中函數(shù)有參數(shù)和包含子函數(shù)
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測(cè)試練習(xí)
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執(zhí)行順序全面詳解的詳細(xì)內(nèi)容,更多關(guān)于golang defer執(zhí)行順序的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
一些關(guān)于Go程序錯(cuò)誤處理的相關(guān)建議
錯(cuò)誤處理在每個(gè)語(yǔ)言中都是一項(xiàng)重要內(nèi)容,眾所周知,通常寫程序時(shí)遇到的分為異常與錯(cuò)誤兩種,Golang中也不例外,這篇文章主要給大家介紹了一些關(guān)于Go程序錯(cuò)誤處理的相關(guān)建議,需要的朋友可以參考下2021-09-09
Go語(yǔ)言實(shí)現(xiàn)Snowflake雪花算法
雪花算法產(chǎn)生的背景當(dāng)然是twitter高并發(fā)環(huán)境下對(duì)唯一ID生成的需求,得益于twitter內(nèi)部牛的技術(shù),雪花算法能夠流傳于至今并且被廣泛使用,本文就詳細(xì)的介紹一下,感興趣的可以了解一下2021-06-06
關(guān)于Golang中range指針數(shù)據(jù)的坑詳解
這篇文章主要給大家介紹了關(guān)于Golang中range指針數(shù)據(jù)的坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
在Go網(wǎng)絡(luò)請(qǐng)求中配置代理的方法詳解
這篇文章主要給大家介紹了如何在Go網(wǎng)絡(luò)請(qǐng)求中配置代理的方法,文章通過代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-09-09
以go為例探究beyla從環(huán)境變量BEYLA_OPEN_PORT發(fā)現(xiàn)進(jìn)程原理
這篇文章主要為大家介紹了以golang進(jìn)程為例,研究beyla從環(huán)境變量BEYLA_OPEN_PORT(即通過端口)發(fā)現(xiàn)進(jìn)程的原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
golang?metrics各個(gè)指標(biāo)含義講解說(shuō)明
這篇文章主要為大家介紹了golang?metrics各個(gè)指標(biāo)含義講解說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05

