亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go語言defer與return執(zhí)行的先后順序詳解

 更新時間:2022年12月12日 10:46:24   作者:捶捶自己  
這篇文章主要為大家介紹了Go語言defer與return執(zhí)行的先后順序詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

先了解什么是defer

Go語言中的defer與return執(zhí)行的先后順序

Go語言的 defer 語句會將其后面跟隨的語句進行延遲處理,在 defer 歸屬的函數(shù)即將返回時,將延遲處理的語句按 defer 的逆序進行執(zhí)行.也就是說,先被 defer 的語句最后被執(zhí)行,最后被 defer 的語句,最先被執(zhí)行。(與棧的先入后出是一個道理,也可以將其理解為入棧和出棧)

舉一個簡單的例子

func main() {
   a, b := 111, 333
   defer fmt.Println("b= ", b)
   fmt.Println("a= ", a)
}
打印結(jié)果:
a=  111
b=  333

可以看到雖然執(zhí)行語句時b在前,但是輸出結(jié)果為b在最后被輸出。

defer 的用法

(簡單講解,細節(jié)請自行查閱資料)

一般用來釋放資源或者讀寫操作,當處理業(yè)務或邏輯中涉及成對的操作是一件比較煩瑣的事情,比如打開和關閉文件、接收請求和回復請求、加鎖和解鎖等。在這些操作中,最容易忽略的就是在每個函數(shù)退出處正確地釋放和關閉資源。比如下面一個例子

func main(){
    a := 1
    out := bufio.NewWriter(os.Stdout)
    defer out.Flush()
    fmt.Fprintln(out, a)
}
輸出結(jié)果:
1

就可以在最后將結(jié)果打印到控制臺中去,類似的用法如關閉數(shù)據(jù)庫資源等等。如果這個例子太過于簡單,那么來看下個例子。

var a bool = true
defer func() {
   fmt.Println("1")
}()
if a == true {
   fmt.Println("2")
   return
}
defer func() {
   fmt.Println("3")
}()
輸出結(jié)果:
2
1

我們會發(fā)現(xiàn)defer語句也是需要被執(zhí)行的,如果在defer函數(shù)執(zhí)行之前就執(zhí)行return。defer后的語句就不會再被執(zhí)行了。但是如果是在return之前defer已經(jīng)執(zhí)行,則defer中的語句將會在return執(zhí)行之前先一步進行執(zhí)行.

那么defer 和 return有什么聯(lián)系?

defer 是延遲執(zhí)行語句,return是返回語句,那么肯定出現(xiàn)誰先誰后的問題。下面看一個經(jīng)典的例子吧

func increaseA() int {
	var i int
	defer func() {
		i++
	}()
	return i
}
func increaseB() (r int) {
	defer func() {
		r++
	}()
	return r
}
func main() {
	fmt.Println(increaseA())
	fmt.Println(increaseB())
}
輸出結(jié)果為:
0
1

肯定有人覺得有疑惑,為什么A函數(shù)沒有輸出,B函數(shù)卻輸出了呢?為什么答案不是1和0呢?

原因:

先說結(jié)論:defer 修飾的匿名函數(shù),只能更新具名返回值.那么這會導致什么問題呢?我們來逐步分析這個例子。

  • 在increaseA()函數(shù)中有一個聲明i,表示i在該函數(shù)內(nèi)已經(jīng)被生成,是有名稱的變量。但該函數(shù)返回參數(shù)為匿名參數(shù).
  • 在increaseB()函數(shù)中沒有聲明r,是匿名變量。但該函數(shù)返回參數(shù)為具名參數(shù).
  • func increaseA() int,返回值i=0的時候該值已經(jīng)被綁定到返回值里了,defer再去改i已經(jīng)沒用了.
  • func increaseB() (r int), 返回值r先把返回變量設為0,defer又把r改為1.這時候還能生效. 因此答案很明顯為 1 和 0.

更進一步理解

我們?nèi)粝胍M一步理解也可以去輸出匯編語句,然后進行研讀,可惜我是個菜鳥讀不懂匯編語言!但我們可以從return入手

我們要理解return 返回值的運行機制:

return并非原子操作,分為賦值,和返回值兩步操作.實際上return 執(zhí)行了兩步操作,因為返回值沒有命名,所以return默認指定了一個返回值(假設為a),首先將i賦值給a,后續(xù)的操作因為是針對i進行的,所以不會影響a, 此后因為a不會更新,所以return a不會改變.

var i int  
a := i  
return a

但是如果return的參數(shù)a是具名參數(shù),就像上述例子中increaseB()函數(shù)一樣。a就相當于命名的變量i, 因為所有的操作都是基于命名變量i(a),返回值也是i, 所以每一次defer操作,都會更新返回值i.

省流小結(jié)

return會將返回值先保存起來,對于無名返回值來說,保存在一個臨時對象中,defer是看不到這個臨時對象的;而對于有名返回值來說,就保存在已命名的變量中。

以上就是Go語言defer與return執(zhí)行的先后順序詳解的詳細內(nèi)容,更多關于Go defer return執(zhí)行順序的資料請關注腳本之家其它相關文章!

相關文章

  • golang中連接mysql數(shù)據(jù)庫

    golang中連接mysql數(shù)據(jù)庫

    這篇文章主要介紹了golang中連接mysql數(shù)據(jù)庫的步驟,幫助大家更好的理解和學習go語言,感興趣的朋友可以了解下
    2020-12-12
  • Go語言中循環(huán)Loop的用法介紹

    Go語言中循環(huán)Loop的用法介紹

    這篇文章介紹了Go語言中循環(huán)Loop的用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • go mod 依賴管理的具體使用

    go mod 依賴管理的具體使用

    在Go語言開發(fā)中,依賴管理是一項非常重要的工作,Go mod作為官方的包管理工具已經(jīng)成為了Go語言依賴管理的首選方式,本文就來介紹一下go mod 依賴管理的具體使用,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • 簡單聊聊Go?for?range中容易踩的坑

    簡單聊聊Go?for?range中容易踩的坑

    for循環(huán)問題,在面試中經(jīng)常都會被問到,并且在實際業(yè)務項目中也經(jīng)常用到for循環(huán),要是沒用好,一不下心就掉坑,本文就來講講Go?for?range中容易踩的坑吧
    2023-03-03
  • go goroutine 怎樣進行錯誤處理

    go goroutine 怎樣進行錯誤處理

    在 Go 語言程序開發(fā)中,goroutine 的使用是比較頻繁的,因此在日常編碼的時候 goroutine 里的錯誤處理,怎么做會比較好呢,本文就來詳細介紹一下
    2021-07-07
  • 利用golang進行OpenCV學習和開發(fā)的步驟

    利用golang進行OpenCV學習和開發(fā)的步驟

    目前,OpenCV逐步成為一個通用的基礎研究和產(chǎn)品開發(fā)平臺,下面這篇文章主要給大家介紹了關于利用golang進行OpenCV學習和開發(fā)的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-09-09
  • Golang Gorm實現(xiàn)自定義多態(tài)模型關聯(lián)查詢

    Golang Gorm實現(xiàn)自定義多態(tài)模型關聯(lián)查詢

    GORM 是一個流行的開源 ORM (Object-Relational Mapping) 庫,專為 Go 語言設計,它簡化了與 SQL 數(shù)據(jù)庫的交互,GORM 封裝了數(shù)據(jù)庫操作,使得開發(fā)者能夠通過簡單的鏈式調(diào)用來執(zhí)行 CRUD,本文給大家介紹了Golang Gorm實現(xiàn)自定義多態(tài)模型關聯(lián)查詢,需要的朋友可以參考下
    2024-11-11
  • go語言K8S?的?informer機制淺析

    go語言K8S?的?informer機制淺析

    這篇文章為大家主要介紹了go語言K8S?的?informer機制淺析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • golang gorm 計算字段和獲取sum()值的實現(xiàn)

    golang gorm 計算字段和獲取sum()值的實現(xiàn)

    這篇文章主要介紹了golang gorm 計算字段和獲取sum()值的實現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang中的信號(Signal)機制詳解

    Golang中的信號(Signal)機制詳解

    Signal 是一種操作系統(tǒng)級別的事件通知機制,進程可以響應特定的系統(tǒng)信號,這些信號用于指示進程執(zhí)行特定的操作,如程序終止、掛起、恢復等,Golang 的標準庫 os/signal 提供了對信號處理的支持,本文將詳細講解 Golang 是如何處理和響應系統(tǒng)信號的,需要的朋友可以參考下
    2024-01-01

最新評論