自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Defer 的變量快照什么情況會失效?

開發(fā) 前端
仔細觀察,可以發(fā)現(xiàn)上面的兩個例子的區(qū)別就在于,一個 defer 后接的是單個表達式,另一個 defer 后接的是一個函數(shù),并且不是普通函數(shù),而是一個匿名的閉包函數(shù)。

[[433813]]

本篇問題:Go 中閉包的底層原理?

關于 defer 的基本知識點,我在以前的教程中有寫過:14. Go語言流程控制:defer 延遲調用

其中有一個知識是 defer 的變量快照,舉個簡單的例子來說

在下面這段代碼中,會先打印出來 18,即使后面 age 已經被改變了,可 defer 中的 age還是 修改之前的 0,這種現(xiàn)象稱之為變量快照。

  1. func func1() { 
  2.     age := 0 
  3.     defer fmt.Println(age) // output: 0 
  4.  
  5.     age = 18 
  6.     fmt.Println(age)      // output: 18 
  7.  
  8.  
  9. func main() { 
  10.     func1() 

對于這個輸出結果,相信還是挺容易理解的。

接下來,我請大家再看下面這個例子,可以猜猜看會輸出什么?

  1. func func1() { 
  2.     age := 0 
  3.     defer func() { 
  4.         fmt.Println(age) 
  5.     }() 
  6.     age = 18 
  7.     return 
  8.  
  9. func main() { 
  10.     func1() 

正確的答案是:18, 而不是 0

你肯定會納悶:不對啊,defer 不是會對變量的值做一個快照嗎?答案應該是 0 啊,為什么會是 18?

實際上,仔細觀察,可以發(fā)現(xiàn)上面的兩個例子的區(qū)別就在于,一個 defer 后接的是單個表達式,另一個 defer 后接的是一個函數(shù),并且不是普通函數(shù),而是一個匿名的閉包函數(shù)。

根據(jù)閉包的特性,實際上在閉包函數(shù)存的是 age 這個變量的指針(原因可以查看上一篇文章:Go 面試題 013:Go 中閉包的底層原理是?),因而,在 defer 后所修改的值會直接影響到 defer 中的 age 的值。

總結一下:

  • 若 defer 后接的是單行表達式,那defer 中的 age 只是拷貝了 func1 函數(shù)棧中 defer 之前的 age 的值;
  • 若 defer 后接的是閉包函數(shù),那defer 中的 age 只是存儲的是 func1 函數(shù)棧中 age 的指針。

本文轉載自微信公眾號「Go編程時光」,可以通過以下二維碼關注。轉載本文請聯(lián)系Go編程時光公眾號。

 

責任編輯:武曉燕 來源: Go編程時光
相關推薦

2022-06-27 07:23:44

MySQL常量優(yōu)化

2022-09-14 19:50:22

事務場景流程

2012-04-25 09:24:40

Android

2024-11-20 08:00:00

死鎖多線程編程

2024-07-05 10:19:59

2021-04-13 13:18:11

數(shù)字貨幣加密貨幣區(qū)塊鏈

2011-12-11 11:51:28

2023-11-23 23:52:06

options請求瀏覽器

2022-04-13 20:53:15

Spring事務管理

2013-09-12 10:41:39

VDI部署

2021-09-14 07:26:25

雪花算法ID

2013-07-29 14:50:43

API

2020-10-16 17:20:21

索引MySQL數(shù)據(jù)庫

2013-09-04 15:17:38

2011-12-28 15:24:21

2015-11-23 14:29:16

流量提速降費運營商

2021-04-23 23:19:26

加密貨幣穩(wěn)定幣比特幣

2021-04-15 08:01:27

Spring聲明式事務

2010-07-13 16:07:26

SQL Server行

2015-08-25 10:54:02

點贊
收藏

51CTO技術棧公眾號