Golang函數中defer的作用以及細節

defer是什麼?

    在Go語言中,可以使用關鍵字defer向函數註冊退出調用,即主函數退出時,defer後的函數才被調用。defer語句的作用是不管程序是否出現異常,均在函數退出時自動執行相關代碼。 

defer的用途

在函數中,程序員經常需要創建資源(比如:數據庫連接、文件句柄、鎖等) ,爲了在函數執行完 畢後,及時的釋放資源,Go 的設計者提供 defer (延時機制)

package main

import "fmt"
//defer  可以向函數註冊、退出調用,即當主調函數退出時,defer後的函數才被調用,
// defer語句的作用就是不管程序是否出現異常,均在函數退出是自動執行相關代碼

func sum(n1 int,n2 int) int{
   //當執行到defer時,暫時不執行,會將defer後面的語句壓入到獨立的(defer棧)
   //當函數執行完畢後,再從defer棧 安裝先入後出的方式出棧執行
   //defer 將語句放入到棧時,也會將相關的值拷貝同時入棧***
   defer  fmt.Println("ok1 n1=",n1)//defer3   ok3   n1  20
   defer  fmt.Println("ok2 n2=",n2) //defer2  ok2 n2  10
   //n1 ++
   //n2 ++

    res := n1 + n2
    fmt.Println("ok3 res=",res)//1.ok1
    return  res
}
func  main()  {
   res :=sum(20,10)
   fmt.Println("res=",res)

}

執行結果

image.png

結果分析:

   從執行結果來看,res=30 是最先開始執行的部分,接下來是第二個defer n2爲10 最後執行的是第一個defer n1爲20 ,即當執行到defer時,暫時不執行,會將defer後面的語句壓入到獨立的(defer棧),當函數執行完畢後,再從defer棧,按照(先入後出)的方式出棧執行。


注意事項:

1) go 執行到一個 defer 時,不會立即執行 defer 後的語句,而是將 defer 後的語句壓入到一個棧 中[我爲了講課方便,暫時稱該棧爲 defer ], 然後繼續執行函數下一個語句。

2) 當函數執行完畢後,在從 defer 棧中,依次從棧頂取出語句執行(注:遵守棧 先入後出的機制),

3) defer 將語句放入到棧時,也會將相關的值拷貝同時入棧

package main

import "fmt"
//defer  可以向函數註冊、退出調用,即當主調函數退出時,defer後的函數才被調用,
// defer語句的作用就是不管程序是否出現異常,均在函數退出是自動執行相關代碼

func sum(n1 int,n2 int) int{
   //當執行到defer時,暫時不執行,會將defer後面的語句壓入到獨立的(defer棧)
   //當函數執行完畢後,再從defer棧 安裝先入後出的方式出棧執行
   //defer 將語句放入到棧時,也會將相關的值拷貝同時入棧***
   defer  fmt.Println("ok1 n1=",n1)//defer3   ok3   n1  20
   defer  fmt.Println("ok2 n2=",n2) //defer2  ok2 n2  10
   n1 ++
   n2 ++

    res := n1 + n2
    fmt.Println("ok3 res=",res)//1.ok1
    return  res
}
func  main()  {
   res :=sum(20,10)
   fmt.Println("res=",res)

}

執行結果:

image.png

從結果看出n1++ ,n2++兩個的值未入相關defer的棧,即defer 將語句放入到棧時,也會將相關的值拷貝同時入棧。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章