深入理解 Go Defer的機制

2021-09-13 04:11:51 字數 2711 閱讀 8428

go 的 defer 語句是用來延遲執行函式的,而且延遲發生在呼叫函式 return之後,比如

func a() int
b 的執行是發生在return 0之後,注意defer的語法,關鍵字defer之後是函式的呼叫。

由於defer的延遲特性,defer常用在函式呼叫結束之後清理相關的資源,比如

f, _ := os.open(filename)

defer f.close()

檔案資源的釋放會在函式呼叫結束之後借助defer自動執行,不需要時刻記住**的資源需要釋放,開啟和釋放必須相對應。

用乙個例子深刻詮釋一下defer帶來的便利和簡潔。

**的主要目的是開啟乙個檔案,然後複製內容到另乙個新的檔案中,沒有defer時這樣寫:

func copyfile(dstname, srcname string) (written int64, err error) 

dst, err := os.create(dstname)

if err != nil

written, err = io.copy(dst, src)

dst.close()

src.close()

return

}

**在#1處返回之後,src檔案沒有執行關閉操作,可能會導致資源不能正確釋放,改用defer實現:

func copyfile(dstname, srcname string) (written int64, err error) 

defer src.close()

dst, err := os.create(dstname)

if err != nil

defer dst.close()

return io.copy(dst, src)

}

srcdst都能及時清理和釋放,無論return在什麼地方執行。

鑑於defer的這種作用,defer常用來釋放資料庫連線,檔案開啟控制代碼等釋放資源的操作。

###defer的重要用途二:執行recover

defer的函式在return之後執行,這個時機點正好可以捕獲函式丟擲的panic,因而defer的另乙個重要用途就是執行recover

recover只有在defer中使用才更有意義,如果在其他地方使用,由於program已經呼叫結束而提前返回而無法有效捕捉錯誤。

package main

import (

"fmt"

)func main()

}()panic("error")

}

記住defer要放在panic執行之前。

defer 的作用就是把關鍵字之後的函式執行壓入乙個棧中延遲執行,多個defer的執行順序是後進先出lifo

defer func() ()

defer func() ()

defer func() ()

輸出順序是 321。

這個特性可以對乙個array實現逆序操作。

這是defer的特點,乙個函式被defer時,它的引數在defer時進行計算確定,即使defer之後引數發生修改,對已經defer的函式沒有影響,什麼意思?看例子:

func a()
a 執行輸出的是 0 而不是 1,因為defer時,i 的值是 0,此時被defer的函式引數已經進行執行計算並確定了。

再看乙個例子:

func calc(index string, a, b int) int 

func main()

執行**輸出

10 1 2 3 

1 1 3 4

defer函式的引數 第三個引數在defer時就已經計算完成並確定,第二個引數 a 也是如此,無論之後 a 變數是否修改都不影響。

func c() (i int) ()

return 1

}

defer的函式是在return之後執行,可以修改帶名稱的返回值,上面的函式 c 返回的是 2。

深入理解Android Binder機制的幾點

android系統binder機制中的四個元件 client,server,service manager和binder驅動程式。1.client server和service manager實現在使用者空間中,binder驅動程式實現在核心空間中 2.binder驅動程式和service mana...

深入理解共享記憶體機制

共享記憶體可以說是最有用的程序間通訊方式,也是最快的ipc形式。是針對其他通訊機制執行效率較低而設計的。兩個不同程序a b共享記憶體的意思是,同一塊物理記憶體被對映到程序a b各自的程序位址空間。程序a可以即時看到程序b對共享記憶體中資料的更新,反之亦然。由於多個程序共享同一塊記憶體區域,必然需要某...

深入理解Java多型機制

目錄 1,多型的概念?2,存在的條件?3,案列解析?4,應用場景?1,多型的概念 父類引用指向子類物件,通俗點就是,在編譯時不繫結是什麼方法,根據你傳進來的值,是什麼就會執行什麼。2.存在條件 第一,要有繼承 第二,要有方法的重寫 第三,父類引用指向子類物件 3,案列解析 好好體會以下這個案例,通過...