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: 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僅有最后一個(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 panic
defer中函數(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
測試練習(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í)行順序的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
一些關(guān)于Go程序錯(cuò)誤處理的相關(guān)建議
錯(cuò)誤處理在每個(gè)語言中都是一項(xiàng)重要內(nèi)容,眾所周知,通常寫程序時(shí)遇到的分為異常與錯(cuò)誤兩種,Golang中也不例外,這篇文章主要給大家介紹了一些關(guān)于Go程序錯(cuò)誤處理的相關(guān)建議,需要的朋友可以參考下2021-09-09Go語言實(shí)現(xiàn)Snowflake雪花算法
雪花算法產(chǎn)生的背景當(dāng)然是twitter高并發(fā)環(huán)境下對唯一ID生成的需求,得益于twitter內(nèi)部牛的技術(shù),雪花算法能夠流傳于至今并且被廣泛使用,本文就詳細(xì)的介紹一下,感興趣的可以了解一下2021-06-06關(guān)于Golang中range指針數(shù)據(jù)的坑詳解
這篇文章主要給大家介紹了關(guān)于Golang中range指針數(shù)據(jù)的坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02以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-12golang?metrics各個(gè)指標(biāo)含義講解說明
這篇文章主要為大家介紹了golang?metrics各個(gè)指標(biāo)含義講解說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05