go defer、return的執行順序
一、一個函數中多個defer的執行順序
defer 的作用就是把defer關鍵字之後的函數執行壓入一個棧中延遲執行,多個defer的執行順序是後進先出LIFO,也就是先執行最後一個defer,最後執行第一個defer
eg:

輸出:

二、defer、return、返回值的執行返回值順序
在此之前,先理解一下return返回值的運行機制:return並非原子操作,共分為賦值、返回值兩步操作。
defer、return、返回值三者的執行是:return最先執行,先將結果寫入返回值中(即賦值);接著defer開始執行一些收尾工作;最後函數攜帶當前返回值退出(即返回值)。
1、不帶命名返回值
如果函數的返回值是無名的(不帶命名返回值),則go語言會在執行return的時候會執行一個類似創建一個臨時變數作為保存return值的動作。
eg:

輸出:

解釋:
如上例子,實際上一共執行了3步操作,
1)賦值,因為返回值沒有命名,所以return 默認指定了一個返回值(假設為s),首先將i賦值給s,i初始值是0,所以s也是0
2)後續的defer操作因為是針對i,進行的,所以不會影響s, 此後因為s不會更新,所以s不會變還是0
3)返回值,return s,也就是return 0
相當於:
var i int
s := i
return s
2、有名返回值
有名返回值的函數,由於返回值在函數定義的時候已經將該變數進行定義,在執行return的時候會先執行返回值保存操作,而後續的defer函數會改變這個返回值(雖然defer是在return之後執行的,但是由於使用的函數定義的變數,所以執行defer操作後對該變數的修改會影響到return的值。
eg:

輸出:

解釋:
s 就相當於命名的變數i,因為所有的操作都是基於命名變數i(s),返回值也是i,所以每一次defer操作,都會更新返回值,執行完defer後,會返回最終i的值。

