欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Go中defer與return的執(zhí)行順序

 更新時間:2023年07月24日 10:24:56   作者:nil  
Go?defer中改變return的值會生效嗎,這就設計到了GO語言中defer與return哪個先執(zhí)行的問題了,下面小編就通過簡單的示例來和大家講講吧

示例

直接上代碼

func test() int {
   result = 123
   defer func() {
      result = 456
   }()
   return result
}
func main() {
   fmt.Println(test())
}

結果

123

修改之后的代碼

func test() (result int) {
   result = 123
   defer func() {
      result = 456
   }()
   return result
}
func main() {
   fmt.Println(test())
}

結果

456

再看下面這個例子

func test() (result int) {
   result = 123
   defer func() {
      fmt.Println("aaa")
      result = 456
   }()
   return func() int {
      fmt.Println("bbb")
      return result
   }()
}
func main() {
   fmt.Println(test())
}

結果

bbb
aaa
456

defer與return哪個先執(zhí)行

這個問題主要是defer 與return哪個先執(zhí)行。很容易理解如果一個函數(shù)中有多個defer,它是棧的形式保存的,執(zhí)行的時候先從棧頂執(zhí)行,即后面定義的defer會先被執(zhí)行,并且defer是在return執(zhí)行之后才執(zhí)行的。

因為defer是在return 執(zhí)行之后才執(zhí)行的,所以第三個例子中先打印bbb后打印aaa很好理解。

第二個例子和第三個例子test函數(shù)返回456也好理解,因為defer可以改變返回值中定義的變量。雖然return已經返回了,defer還是可以改變它。

第一個例子,defer改變的不是返回值中定義的變量,而是局部變量,這個時候return已經執(zhí)行了,defer改變局部變量沒有用。在defer中改變局部變量的值沒有效果。第一個例子return result是值拷貝,即將result的值拷貝一份并返回,因此defer改變result并不會影響返回值。

第二、第三例子中return返回的result不是值拷貝,因為result是在返回值中定義的變量,所以return返回的直接是那個變量,這個時候沒有值拷貝

再看看下面這個例子

func test() *int {
   result := 123
   defer func() {
      result = 456
   }()
   return &result
}
func main() {
   fmt.Println(*test())
}

結果

456

這個時候defer改變局部變量result又生效了,這是為什么?是因為return 返回的是局部變量的地址,而不是局部變量的只拷貝。因此在defer中修改局部遍歷會影響返回結果。

總結

上面描述可能有點繞,需要親自實驗一下,仔細理解才能真正搞懂。下面總結一下我的理解:

return 返回有2種方式:

值拷貝:將局部變量的值拷貝到返回值上。return 直接返回局部變量的值(不是局部變量的引用)

非值拷貝:即return 返回值的時候沒有發(fā)生值拷貝,有兩種情況:

  • 將返回值中定義的變量返回。
  • 將局部變量的引用返回。

非值拷貝的情況下,defer修改返回值是生效的。

return 的執(zhí)行其實用兩步驟:1.先將return的結果賦值到返回值上;2.再將返回值賦值作為函數(shù)的結果賦值給調用者。

defer的執(zhí)行是在return的兩步驟中間執(zhí)行的。所以return如果發(fā)生了值拷貝則defer不會改變返回結果;如果return沒有發(fā)生值拷貝則defer會改變返回結果。

到此這篇關于詳解Go中defer與return的執(zhí)行順序的文章就介紹到這了,更多相關Go defer return內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • GO語言操作Elasticsearch示例分享

    GO語言操作Elasticsearch示例分享

    這篇文章主要介紹了GO語言操作Elasticsearch示例分享的相關資料,需要的朋友可以參考下
    2023-01-01
  • golang?JSON序列化和反序列化示例詳解

    golang?JSON序列化和反序列化示例詳解

    通過使用Go語言的encoding/json包,你可以輕松地處理JSON數(shù)據(jù),無論是在客戶端應用、服務器端應用還是其他類型的Go程序中,這篇文章主要介紹了golang?JSON序列化和反序列化,需要的朋友可以參考下
    2024-04-04
  • go?mod文件內容版本號簡單用法詳解

    go?mod文件內容版本號簡單用法詳解

    這篇文章主要為大家介紹了go?mod文件內容版本號簡單用法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • Go開發(fā)Gin項目添加jwt功能實例詳解

    Go開發(fā)Gin項目添加jwt功能實例詳解

    這篇文章主要為大家介紹了Go開發(fā)Gin項目中添加jwt功能實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • GoLang bytes.Buffer基礎使用方法詳解

    GoLang bytes.Buffer基礎使用方法詳解

    Go標準庫中的bytes.Buffer(下文用Buffer表示)類似于一個FIFO的隊列,它是一個流式字節(jié)緩沖區(qū),我們可以持續(xù)向Buffer尾部寫入數(shù)據(jù),從Buffer頭部讀取數(shù)據(jù)。當Buffer內部空間不足以滿足寫入數(shù)據(jù)的大小時,會自動擴容
    2023-03-03
  • Go高級特性探究之穩(wěn)定排序詳解

    Go高級特性探究之穩(wěn)定排序詳解

    Go 語言提供了 sort 包,其中最常用的一種是 sort.Slice() 函數(shù),本篇文章將為大家介紹如何使用 sort.SliceStable() 對結構體數(shù)組的某個字段進行穩(wěn)定排序,感興趣的可以了解一下
    2023-06-06
  • 5個可以在Golang中優(yōu)化代碼以提高性能的技巧分享

    5個可以在Golang中優(yōu)化代碼以提高性能的技巧分享

    作為一名軟件工程師,確保你的代碼高效且性能良好是非常重要的。本文主要和大家分享5個可以在Golang中優(yōu)化代碼以提高性能的技巧,希望對大家有所幫助
    2023-03-03
  • Go?1.21新內置函數(shù)min、max和clear的用法詳解

    Go?1.21新內置函數(shù)min、max和clear的用法詳解

    Go?1.21?版本已經正式發(fā)布,它帶來了許多新特性和改進,其中引入了的三個新內置函數(shù):max、min?和?clear,接下來我們就來看看這些函數(shù)的用途和特點吧
    2023-08-08
  • Go利用GJSON組件解鎖JSON讀取新姿勢

    Go利用GJSON組件解鎖JSON讀取新姿勢

    Go 標準庫提供了 encoding/json 包用于處理 json 數(shù)據(jù),同時第三方庫 GJSON & SJSON 也在 json 處理方面表現(xiàn)出色,下面我們就來看看如何使用GJSON解鎖JSON讀取新方法吧
    2025-03-03
  • Golang timer可能造成的內存泄漏問題分析

    Golang timer可能造成的內存泄漏問題分析

    本文探討了Golang中timer可能造成的內存泄漏問題,通過分析一段代碼,解釋了為什么協(xié)程在調用timer.Stop()后無法正常退出,文章指出,timer.Stop()并不關閉Channel,導致協(xié)程無法繼續(xù)執(zhí)行,最后,提出了一種修復方法,并呼吁大家關注和分享
    2024-12-12

最新評論