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

defer是什麼?程序員

    在Go語言中,能夠使用關鍵字defer向函數註冊退出調用,即主函數退出時,defer後的函數才被調用。defer語句的做用是無論程序是否出現異常,均在函數退出時自動執行相關代碼。 數據庫

defer的用途bash

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

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

結果分析:spa

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


注意事項:blog

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

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

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 將語句放入到棧時,也會將相關的值拷貝同時入棧。

相關文章
相關標籤/搜索