91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go defer的作用是什么

發布時間:2021-07-10 11:35:32 來源:億速云 閱讀:276 作者:chen 欄目:編程語言

這篇文章主要介紹“go defer的作用是什么”,在日常操作中,相信很多人在go defer的作用是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”go defer的作用是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

 

defer 關鍵字

很多現代的編程語言中都有 defer 關鍵字,Go 語言的 defer 會在當前函數返回前執行傳入的函數,它會經常被用于關閉文件描述符、關閉數據庫連接以及解鎖資源。

使用 defer 的最常見場景是在函數調用結束后完成一些收尾工作,例如在 defer 中回滾數據庫的事務:

func InsertObj() error {
   //獲取一個數據庫session
   db := db.GetDB().Begin()
   defer db.Rollback()
   
   //do someting
   err := db.Insert()
   
   if err != nil{
    return err
   }
   
   return db.Commit().Error
}
 

在使用數據庫事務時,我們可以使用上面的代碼在創建事務后就立刻調用 Rollback 保證事務一定會回滾。哪怕事務真的執行成功了,那么調用 Commit() 之后再執行 Rollback() 也不會影響已經提交的事務。

 

defer的特性

  • defer 的調用時機以及多次調用     defer 時執行順序
  • defer 使用傳值的方式傳遞參數時會進行預計算,導致不符合預期的結果
func main() {

defer fmt.Println(0)
       defer fmt.Println(1)
       defer fmt.Println(2)
       defer fmt.Println(3)
       
}

 

上面的代碼輸出:

3
2
1
0
 

那么defer的執行順序就是先進后出

func main() {
   {
       defer fmt.Println("defer runs")
       fmt.Println("block ends")
   }
   
   fmt.Println("main ends")
}
 

輸出:

block ends
main ends
defer runs
 

可以看出defer不是在退出代碼塊的作用域時執行的,它只會在當前函數和方法返回之前被調用

 

預計算

func main() {
startedAt := time.Now()
defer fmt.Println(time.Since(startedAt))

time.Sleep(time.Second)
}
 

輸出:

0s
 

調用 defer 關鍵字會立刻拷貝函數中引用的外部參數,所以 time.Since(startedAt) 的結果不是在 main 函數退出之前計算的,而是在 defer 關鍵字調用時計算的,最終導致上述代碼輸出 0s。

那么如果要解決這個問題可以改寫代碼

func main() {
startedAt := time.Now()
defer func() { fmt.Println(time.Since(startedAt)) }()

time.Sleep(time.Second)
}

 

輸出:

1s
 

雖然調用 defer 關鍵字時也使用值傳遞,但是因為拷貝的是函數指針

 

defer 常用的案例

捕獲異常和崩潰日志:

func process() error {
defer func() {
               //防止意外之外的錯誤導致程序崩潰
if err := recover(); err != nil {
                       //崩潰日志的捕獲
core.LogPnc.Errorf("panic : %v", err)
core.LogPnc.Errorf("%s", string(debug.Stack()))
}
}()
       //do something
err := obj.CALL(parseYML)
if err != nil {
return err
}
return nil
}
 

釋放鎖:

func runTask() {
       //上鎖
c.lk.Lock()
       //釋放鎖
defer c.lk.Unlock()
//do something
}

 

在函數返回之前進行業務操作

func (c *ProcessEngine) Process(ph *ProcessHook) {
defer func() {

c.lk.Lock()
               //邏輯處理
c.running--
c.lk.Unlock()


}()
       //do something
}

到此,關于“go defer的作用是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

go
AI

防城港市| 巩留县| 鲁山县| 蒙自县| 贵定县| 新民市| 莫力| 集贤县| 麦盖提县| 高邮市| 西乡县| 图们市| 河北区| 抚远县| 沂水县| 南城县| 惠来县| 环江| 富蕴县| 玉树县| 屏山县| 靖州| 大渡口区| 德江县| 咸宁市| 钟山县| 临湘市| 宁波市| 民乐县| 安乡县| 深泽县| 永靖县| 金山区| 错那县| 巴林右旗| 墨竹工卡县| 吴桥县| 遂宁市| 化德县| 获嘉县| 鹿邑县|