日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Golang——延迟调用defer

發布時間:2025/3/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Golang——延迟调用defer 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

defer用于向當前函數注冊稍后執行的函數調用。這些調用被稱作延遲調用,它們直到當前函數執行結束前才被執行,常用于資源釋放、錯誤處理等操作

func main() {f, err := os.Open("/test.txt")if err != nil {fmt.Println("os.Open err:", err)return}defer f.Close() // 僅注冊,直到main退出前才執行 }

延遲調用注冊的是調用,不是函數,需提供執行所需參數。參數值在注冊時被賦值并緩存起來,如此狀態敏感,可改用指針或閉包。延遲函數返回值會被拋棄

func main() {x, y := 1, 2defer func(a int) {println("defer x, y = ", a, y) // 為閉包引用}(x) // 注冊時復制調用參數x += 100 // 對x的修改,不會影響延遲調用y += 200println(x, y) }

輸出:

101 202 defer x, y = 1 202

多個延遲注冊按FILO次序執行

func main() {defer println("a")defer println("b") }

輸出:

b a

編譯器通過在ret指令前插入指令來實現延遲調用執行,而return和panic語句都會終止 當前函數流程,弓I發延遲調用°return不是ret,它會更新返回值

func main() {println("test:", test()) }func test() (z int) {defer func() {println("defer:", z)z += 100 // 修改命名返回值}()return 100 // 實際執行次序:z = 100, call defer, ret }

輸出:

defer: 100 test: 200

千萬記住,延遲調用是在函數結束時才被執行。不合理的使用方式會浪費更多的資源,甚 至造成邏輯錯誤。

案例:循環處理多個日志文件,defer導致文件關閉時機延長

func main() {for i := 0; i < 10000; i++ {path := fmt.Sprintf("./log/%d.txt", i)f, err := os.Open(path)if err != nil {log.Println(err)continue}defer f.Close()// 這個關閉操作在main函數結束時才會執行,而不是當前循環。// 延長了邏輯結束時間和f生命周期,平白多消耗了內存等資源。 // 編譯器也會提醒:可能發生資源泄漏,在 'for' 循環中調用 'defer' } }

應該直接調用,或重構為函數,讓循環和處理算法分離

func main() {//日志處理算法。do := func(n int) {path := fmt.Sprintf("./log/%d.txt", n)f, err := os.Open(path)if err != nil {log.Println(err)return}defer f.Close() // 該延遲調用在此匿名函數結束時執行,而非main}for i := 0; i < 10000; i++ {do(i)} }

相比直接用CALL指令調用函數,延遲調用則需花費更大代價。這其中包括注冊、調用等 操作,還有額外的緩存開銷。相差幾倍的結果足以引起重視。尤其是那些性能要求高且壓力大的算法,應避免使用

總結

以上是生活随笔為你收集整理的Golang——延迟调用defer的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。