本文由go語言教學專欄給大家介紹,主題是關於go defer的學習使用,希望對需要的朋友有幫助!
什麼是defer?
在Go中,一個函數呼叫可以跟在一個defer
關鍵字後面,形成一個延遲函數呼叫。
當一個函數呼叫被延遲後,它不會立即被執行。它將被推入由當前協程維護的一個延遲呼叫堆疊。當函數呼叫(可能是也可能不是延遲呼叫)返回並進入它的退出階段後,所有在此函數呼叫中已經被推入的延遲呼叫將被按照它們被推入堆疊的順序逆序執行。當所有這些延遲呼叫執行完畢後,此函數呼叫也就真正退出了。
舉個簡單的例子:
package mainimport "fmt"func sum(a, b int) { defer fmt.Println("sum函数即将返回") defer fmt.Println("sum函数finished") fmt.Printf("参数a=%v,参数b=%v,两数之和为%v\n", a, b, a+b)}func main() { sum(1, 2)}
output:
参数a=1,参数b=2,两数之和为3 sum函数finished sum函数即将返回
事實上,每個協程都維護著兩個呼叫堆疊。
- 一個是正常的函數呼叫堆疊。在此堆疊中,相鄰的兩個呼叫存在著呼叫關係。晚進入堆疊的呼叫被早進入堆疊的呼叫所呼叫。此堆疊中最早被推入的呼叫是對應協程的啟動呼叫。
- 另一個堆疊是上面提到的延遲呼叫堆疊。處於延遲呼叫堆疊中的任意兩個呼叫之間不存在呼叫關係。
defer函數參數估值
- #對於一個延遲函數調用,它的實參是在此調用被推入延遲呼叫堆疊的時候被估值的。
- 一個匿名函數體內的表達式是在此函數被執行的時候才會被逐個估值的,不管此函數是被普通呼叫還是延遲呼叫。
範例1:
package mainimport "fmt"func Print(a int) {fmt.Println("defer函数中a的值=", a)}func main() {a := 10defer Print(a)a = 1000fmt.Println("a的值=", a)}
output:
a的值= 1000 defer函数中a的值= 10
defer Print(a) 被加入到延遲呼叫堆疊的時候,a 的值是5,故defer Print(a ) 輸出的結果為5
範例2:
package mainimport "fmt"func main() { func() { for i := 0; i <p>output:</p><pre class="brush:php;toolbar:false">a= 2 a= 1 a= 0 b= 3 b= 3 b= 3
第一個匿名函數循環中的i 是在fmt.Println函數呼叫被推入延遲呼叫堆疊的時候估的值,因此輸出結果是2,1,0 , 第二個匿名函數中的i 是匿名函數呼叫退出階段估的值(此時i 已經變成3了),故結果輸出:3, 3,3。
其實對第二個匿名函數呼叫略加修改,就能讓它輸出和匿名函數一相同的結果:
package mainimport "fmt"func main() { func() { for i := 0; i <p>output:</p><pre class="brush:php;toolbar:false">a= 2 a= 1 a= 0 b= 2 b= 1 b= 0
恐慌(panic)和恢復(defer recover)
Go不支援異常拋出和捕獲,而是建議使用返回值明確傳回錯誤。不過,Go支援一套和異常拋出/捕獲類似的機制。此機制稱為恐慌/恢復(panic/recover)機制。
我們可以呼叫內建函數panic
來產生一個恐慌以使目前協程進入恐慌狀況。
進入恐慌狀況是另一種使當前函數呼叫開始返回的途徑。一旦函數呼叫產生一個恐慌,此函數呼叫將立即進入它的退出階段,在此函數呼叫中被推入堆疊的延遲呼叫將按照它們被推入的順序逆序執行。
透過在一個延遲函數呼叫之中呼叫內建函數recover
,當前協程中的一個恐慌可以被消除,從而使得當前協程重新進入正常狀況。
在一個處於恐慌狀況的協程退出之前,其中的恐慌不會蔓延到其它協程。如果一個協程在恐慌狀況下退出,它將使整個程序崩潰。看下面的兩個例子:
package mainimport ( "fmt" "time")func p(a, b int) int { return a / b}func main() { go func() { fmt.Println(p(1, 0)) }() time.Sleep(time.Second) fmt.Println("程序正常退出~~~")}
output:
panic: runtime error: integer pide by zero goroutine 6 [running]: main.p(...) /Users/didi/Desktop/golang/defer.go:9 main.main.func1() /Users/didi/Desktop/golang/defer.go:14 +0x12 created by main.main /Users/didi/Desktop/golang/defer.go:13 +0x39exit status 2
p函數發生panic(除數為0),因為所在協程沒有恐慌恢復機制,導致整個程式崩潰。
如果p函數所在協程加上恐慌恢復(defer recover),程式便可正常退出。
package mainimport ( "fmt" "time")func p(a, b int) int { return a / b}func main() { go func() { defer func() { v := recover() if v != nil { fmt.Println("恐慌被恢复了:", v) } }() fmt.Println(p(1, 0)) }() time.Sleep(time.Second) fmt.Println("程序正常退出~~~")}
output:
恐慌被恢复了: runtime error: integer pide by zero 程序正常退出~~~
更多golang相關知識,請造訪golang#更多golang相關知識,請造訪
以上是在Go中什麼是defer?怎麼用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Golang和Python的主要區別在於並發模型、類型系統、性能和執行速度。 1.Golang使用CSP模型,適用於高並發任務;Python依賴多線程和GIL,適合I/O密集型任務。 2.Golang是靜態類型,Python是動態類型。 3.Golang編譯型語言執行速度快,Python解釋型語言開發速度快。

Golang通常比C 慢,但Golang在並發編程和開發效率上更具優勢:1)Golang的垃圾回收和並發模型使其在高並發場景下表現出色;2)C 通過手動內存管理和硬件優化獲得更高性能,但開發複雜度較高。

Golang在雲計算和DevOps中的應用廣泛,其優勢在於簡單性、高效性和並發編程能力。 1)在雲計算中,Golang通過goroutine和channel機制高效處理並發請求。 2)在DevOps中,Golang的快速編譯和跨平台特性使其成為自動化工具的首選。

Golang和C 在執行效率上的表現各有優勢。 1)Golang通過goroutine和垃圾回收提高效率,但可能引入暫停時間。 2)C 通過手動內存管理和優化實現高性能,但開發者需處理內存洩漏等問題。選擇時需考慮項目需求和團隊技術棧。

Golang更適合高並發任務,而Python在靈活性上更有優勢。 1.Golang通過goroutine和channel高效處理並發。 2.Python依賴threading和asyncio,受GIL影響,但提供多種並發方式。選擇應基於具體需求。

Golang和C 在性能上的差異主要體現在內存管理、編譯優化和運行時效率等方面。 1)Golang的垃圾回收機制方便但可能影響性能,2)C 的手動內存管理和編譯器優化在遞歸計算中表現更為高效。

selectgolangforhighpperformanceandcorrency,ifealforBackendServicesSandNetwork程序; selectpypypythonforrapiddevelopment,dataScience和machinelearningDuetoitsverserverserverserversator versator anderticality andextility andextentensivelibraries。

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。Golang以其并发模型和高效性能著称,Python则以简洁语法和丰富库生态系统著称。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

禪工作室 13.0.1
強大的PHP整合開發環境

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中