<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
先解釋一下這篇Blog延期的原因,本來已經準備好了全部內容,但是當我重新回顧範例三的時候,發現自己還是存在認知不足的地方,於是為了準確表述,查閱了大量的資料,重新編寫了第三部分,導致延期。感謝持續關注本筆記更新的朋友,後期我將逐步通過3-5分鐘視訊方式為大家對筆記內容進行講解,幫助更多的朋友能夠快速掌握Go語言的基礎。
本節將介紹Go語言函數和方法中的延遲呼叫,正如名稱一樣,這部分定義不會立即執行,一般會在函數返回前再被呼叫,我們通過下面的幾個範例來了解一下延遲呼叫的使用場景。
在以下這段程式碼中,我們操作一個檔案,無論成功與否都需要關閉檔案控制程式碼。這裡在三處不同的位置都呼叫了file.Close()方法,程式碼顯得非常冗餘。
func ReadWrite() bool { file.Open("file") // Do your thing if failureX { file.Close() return false } if failureY { file.Close() return false } file.Close() return true }
我們利用延遲呼叫來優化程式碼。定義後的defer程式碼,會在return之前返回,讓程式碼顯得更加緊湊,且可讀性變強,對上面的程式碼改造如下:
func ReadWrite() bool { file.Open("filename") // Define a defer code here defer file.Close() // Do your thing if failureX { return false } if failureY { return false } return true }
我們通過這個範例來看一下延遲呼叫與正常程式碼之間的執行順序
package main import "fmt" func TestDefer(x int) { defer fmt.Println("Defer code called") switch x { case 1: fmt.Println("Case 1 triggered!") return case 10: fmt.Println("Case 10 triggered!") return default: fmt.Println("Case default triggered!") return } } func main() { TestDefer(100) TestDefer(1) TestDefer(10) }
先簡單分析一下程式碼邏輯:
從輸出中,我們可以觀察到如下現象:
從這個範例中,我們很明顯觀察到,defer語句是在return之前執行
Case default triggered!
Defer code called
Case 1 triggered!
Defer code called
Case 10 triggered!
Defer code called
package main import "fmt" func TestDefer(x int) { defer fmt.Println("1st defined Defer code called") defer fmt.Println("2nd defined Defer code called") defer fmt.Println("3rd defined Defer code called") switch x { case 1: fmt.Println("Case 1 triggered!") return case 10: fmt.Println("Case 10 triggered!") return default: fmt.Println("Case default triggered!") return } } func main() { TestDefer(100) }
仍然是相同的例子,但是在TestDefer中我們定義了三個defer輸出,根據LIFO原則,輸出的順序是3rd->2nd->1st,根據最後的結果,也是逆向向上執行defer輸出。
Case default triggered!
3rd defined Defer code called
2nd defined Defer code called
1st defined Defer code called
就在整理這篇筆記的時候,發現了自己的認知誤區,主要是本節範例三中發現的,先來看一下英文的描述:
A defer statement pushes a function call onto a list. The list of saved calls is executed after the surrounding function returns. Defer is commonly used to simplify functions that perform various clean-up actions.
對於上面的這段話的理解:
defer定義的函數會被放入list中
儲存的defer函數會在周邊函數返回後執行
defer一般用於環境清理
原則一:defer函數的引數值,取決於defer函數呼叫時變數的值
package main import "fmt" func a() int { i := 0 fmt.Printf("func i = %vn", i) defer fmt.Printf("defer i = %vn", i) i++ fmt.Printf("func i = %vn", i) defer fmt.Printf("defer after i++ = %vn", i) return i } func main() { i := a() fmt.Printf("main i = %vn", i) }
下面是程式碼執行輸出,我們來一起分析一下:
func i = 0 func i = 1 defer after i++ = 1 defer i = 0 main i = 1
原則二:defer可以讀取或修改顯示定義的返回值
package main import "fmt" func a() (i int) { fmt.Printf("func initial i = %vn", i) defer func() { fmt.Printf("defer func initial i++ = %vn", i) i++ fmt.Printf("defer func after i++ = %vn", i) }() fmt.Printf("func before return i = %vn", i) return 10 } func main() { i := a() fmt.Printf("main i = %vn", i) }
雖然在a()函數內,顯示的返回了10,但是main函數中得到的結果是defer函數自增後的結果,我們來分析一下程式碼:
在a函數定義時,我們顯示的定義了返回變數i和型別int
在剛剛進入函數時,i的初始化值位0,返回前也是0
在最後的return時,直接返回了10
接著我們再來看defer函數執行情況,剛剛進入defer函數時,返回值i得到的值正是剛才返回的10
而在自增後,i的值變成了11
最後我們在主函數中,獲得的返回值也是11,印證了我們原則中的defer函數對於返回值的讀取和修改
func initial i = 0 func before return i = 0 defer func initial i++ = 10 defer func after i++ = 11 main i = 11
到此這篇關於Go語言函數的延遲呼叫(Deferred Code)詳解的文章就介紹到這了,更多相關Go 函數延遲呼叫內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45