成熟丰满熟妇高潮XXXXX,人妻无码AV中文系列久久兔费 ,国产精品一国产精品,国精品午夜福利视频不卡麻豆

您好,歡迎來到九壹網(wǎng)。
搜索
您的當(dāng)前位置:首頁【go語言】wait,wait for me

【go語言】wait,wait for me

來源:九壹網(wǎng)

去年輸出了一系列g(shù)olang的編碼文章,但總感覺有話沒講,但又不清楚具體是什么,所以本文以隨筆為主。



我們知道函數(shù)的調(diào)用其實(shí)就是一個(gè)入棧和出棧的動(dòng)作:

main() --> normal()


試想當(dāng)執(zhí)行函數(shù)normal()時(shí)出現(xiàn)異常時(shí),會(huì)有什么情況發(fā)生呢?

package main


import (

? ? "fmt"

)


func normal(a int) int {

? ? ? ??var b int = 0

? ? ? ? return a / b

}


func main() {

? ? ? ? var a int =

? ? ? ? fmt.Println("a/b= ", normal(a))

}

你肯定想,這會(huì)拋錯(cuò)呀~

是的,U are right,會(huì)拋出panic: runtime error: integer divide by zero.


進(jìn)一步想,如果var b int = 0不是簡(jiǎn)單的賦值,而是一塊內(nèi)存的分配,不幸的是,剛分配完內(nèi)存就拋異常了,那么該內(nèi)存就永遠(yuǎn)沒有被釋放的機(jī)會(huì)。


如何解決?其它語言有:try、catch、finally等關(guān)鍵字。

golang采用了defer關(guān)鍵字,該關(guān)鍵字用于告訴程序:“wait,wait,我做點(diǎn)事情之后,你再退出本次調(diào)用”。



func normal(a int) int {

? ? ? ??defer fmt.Println("wait, wait for me.")

? ? ? ? var b int = 0

? ? ? ? return a / b

}

修改normal()函數(shù),在函數(shù)體內(nèi)增加defer再運(yùn)行,就會(huì)發(fā)現(xiàn)在拋異常之前把“wait, wait for me.”打印出來了。


這表示在函數(shù)normal()被調(diào)用之后,/0遇到了問題,此時(shí)golang會(huì)拋出panic前,defer說等等,等我打印點(diǎn)東西后,你再拋。



【defer語法】:

defer 表達(dá)式


func normal(a int) int {

? ? ? ??defer?func() {

? ? ? ? ? ? ? ? ?fmt.Println("panic will be throwen.")

? ? ? ??}()

? ? ? ? var b int = 0

? ? ? ? return a / b

}

當(dāng)表達(dá)式是一個(gè)匿名函數(shù)時(shí),一定要記得后面追加(),這表示是一個(gè)表達(dá)式 :)



【defer使用場(chǎng)景】:

defer一般使用在函數(shù)體開始,或者緊跟著申請(qǐng)資源的語句后面

不建議把defer放到函數(shù)體的后面。修改一下上面的示例:

func normal(a int) {

var b int = 0

fmt.Println("a/b= ", a/b)

defer?func() {

fmt.Println("panic will be throwen.")

}()

}


func main() {

var a int =

normal(a)

}

此時(shí)的defer已無意義,所以"panic will be throwen."不會(huì)被打印出來。




【多個(gè)順序defer】:

被調(diào)用函數(shù)中若有多個(gè)順序defer,則先會(huì)出現(xiàn)“先定義后執(zhí)行”現(xiàn)象

func main() {

defer fmt.Println("0")

defer fmt.Println("1")

defer fmt.Println("2")

defer fmt.Println("3")

defer fmt.Println("4")

fmt.Println("Test multi defers")

}

執(zhí)行結(jié)果為:

Test multi defers

4

3

2

1

0

想想這很自然,從堆棧來看,越是后面定義的defer越是處于堆棧的棧頂。


該代碼可以精簡(jiǎn)為:

func main() {

? ? ? ??for i := 0; i < 5; i++ {

? ? ? ? ? ? ? defer fmt.Println(i)

? ? ? ? }

? ? ? ? fmt.Println("Test multi defers")

}



【defer表達(dá)式中存在函數(shù)調(diào)用】:

defer語句被執(zhí)行的時(shí)候,傳遞給延遲函數(shù)的參數(shù)都會(huì)被求值,但是延遲函數(shù)調(diào)用表達(dá)式并不會(huì)在此時(shí)被求值。


感覺這句話比較繞口,不好難理解?先看一個(gè)例子:

func history(date string) string { ?// 打印"2016 will be history",并返回"2017"字符串

s := date + " will be history."

fmt.Println(s)

return "2017"

}


func future(date string) string { ?// 打印"2017 will be coming",并返回"2017 will be coming"字符串

s := date + " will be coming."

fmt.Println(s)

return s

}


func main() {

defer future(history("2016"))

fmt.Println("It's the Spring Festival now.")

}

對(duì)照著defer future(history("2016"))理解一下“傳遞給延遲函數(shù)的參數(shù)都會(huì)被求值,但是延遲函數(shù)調(diào)用表達(dá)式并不會(huì)在此時(shí)被求值”。

  • 延遲函數(shù):future()

  • 延遲函數(shù)的參數(shù):history("2016")

由于延遲函數(shù)的參數(shù)會(huì)被求值,即history("2016")會(huì)被執(zhí)行,所以會(huì)先指印出“2016 will be history”,同時(shí)延遲函數(shù)變?yōu)閒uture("2017"),它要求被延遲執(zhí)行。

從而該程序執(zhí)行結(jié)果為:

2016 will be history.

It's the Spring Festival now.

2017 will be coming.


感覺“defer語句被執(zhí)行的時(shí)候,傳遞給延遲函數(shù)的參數(shù)都會(huì)被求值,但是延遲函數(shù)調(diào)用表達(dá)式并不會(huì)在此時(shí)被求值”這語句已經(jīng)理解了,請(qǐng)?jiān)倏聪旅娴睦樱?/span>

func main() {

for i := 0; i < 5; i++ {

defer func() {

fmt.Println(i)

}()

}

fmt.Println("Test multi defers")

}

它的運(yùn)行結(jié)果為:

Test multi defers

5

5

5

5

5

是不是有點(diǎn)懵逼了?

對(duì)照著defer func(){

? ? ? ? ? ? ? ? ? ? fmt.Println(i)

? ? ? ? ? }()

理解一下“傳遞給延遲函數(shù)的參數(shù)都會(huì)被求值,但是延遲函數(shù)調(diào)用表達(dá)式并不會(huì)在此時(shí)被求值

  • 延遲函數(shù)表達(dá)式:

? ? ? ?func() {

? ? ? ? ? ? ? ?fmt.Println(i)

? ? ? ?}()

在defer語句被執(zhí)行時(shí),該表達(dá)式并不會(huì)被求值,即被執(zhí)行,i值你自己玩吧,所以等循環(huán)完成之后i值變?yōu)?,再打印出“Test multi defers”,函數(shù)馬上要return時(shí),這5個(gè)defer分別說:“wait, wait for me.”。

于是第5個(gè)defer表達(dá)式被執(zhí)行,打印i值(這時(shí)i值為5),所以打印出:

5

于是第4個(gè)defer表達(dá)式被執(zhí)行,打印i值(這時(shí)i值為5),所以打印出:

5

于是第3個(gè)defer表達(dá)式被執(zhí)行,打印i值(這時(shí)i值為5),所以打印出:

5

于是第2個(gè)defer表達(dá)式被執(zhí)行,打印i值(這時(shí)i值為5),所以打印出:

5

于是第1個(gè)defer表達(dá)式被執(zhí)行,打印i值(這時(shí)i值為5),所以打印出:

5

從而出現(xiàn)該結(jié)果 :)



接下來咋玩?

func main() {

for i := 0; i < 5; i++ {

defer func(n int) {

fmt.Println(n)

}(i)

}

fmt.Println("Test multi defers")

}

再理解"defer語句被執(zhí)行的時(shí)候,傳遞給延遲函數(shù)的參數(shù)都會(huì)被求值,但是延遲函數(shù)調(diào)用表達(dá)式并不會(huì)在此時(shí)被求值"一下:

當(dāng)i=0時(shí)

  • 延遲函數(shù)調(diào)用表達(dá)式:func(n int) { fmt.Println(n) }(i)

  • 延遲函數(shù)的參數(shù):n

延遲函數(shù)調(diào)用表達(dá)式不會(huì)被求值,但延遲函數(shù)的參數(shù)i會(huì)被求值,所以n值變?yōu)?


當(dāng)i=1時(shí)

  • 延遲函數(shù)調(diào)用表達(dá)式:func(n int) { fmt.Println(n) }(i)

  • 延遲函數(shù)的參數(shù):n

延遲函數(shù)調(diào)用表達(dá)式不會(huì)被求值,但延遲函數(shù)的參數(shù)i會(huì)被求值,所以n值變?yōu)?


依次類推,從而最終執(zhí)行結(jié)果為:

Test multi defers

4

3

2

1

0



defer好玩吧,上面的例子有的來源自于網(wǎng)絡(luò)上其他人的博客。

因篇幅問題不能全部顯示,請(qǐng)點(diǎn)此查看更多更全內(nèi)容

Copyright ? 2019- 91gzw.com 版權(quán)所有 湘ICP備2023023988號(hào)-2

違法及侵權(quán)請(qǐng)聯(lián)系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市萬商天勤律師事務(wù)所王興未律師提供法律服務(wù)