掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
變量的生命周期指的是在程序運(yùn)行期間變量有效存在的時(shí)間間隔。

變量的生命周期與 變量的作用域有著不可分割的聯(lián)系:
for t := 0.0; t < cycles*2*math.Pi; t += res {
x := math.Sin(t)
y := math.Sin(t*freq + phase)
img.SetColorIndex(
size+int(x*size+0.5), size+int(y*size+0.5),
blackIndex, // 最后插入的逗號(hào)不會(huì)導(dǎo)致編譯錯(cuò)誤,這是Go編譯器的一個(gè)特性
) // 小括號(hào)另起一行縮進(jìn),和大括號(hào)的風(fēng)格保存一致
} 上面代碼中,在每次循環(huán)的開始會(huì)創(chuàng)建臨時(shí)變量 t,然后在每次循環(huán)迭代中創(chuàng)建臨時(shí)變量 x 和 y。臨時(shí)變量 x、y 存放在棧中,隨著函數(shù)執(zhí)行結(jié)束(執(zhí)行遇到最后一個(gè)
}),釋放其內(nèi)存。
棧的概念在上一節(jié)《 變量逃逸》中介紹過,它和堆的區(qū)別在于:
{ }中定義的局部變量。在程序的編譯階段,編譯器會(huì)根據(jù)實(shí)際情況自動(dòng)選擇在?;蛘叨焉戏峙渚植孔兞康拇鎯?chǔ)空間,不論使用 var 還是 new 關(guān)鍵字聲明變量都不會(huì)影響編譯器的選擇。
var global *int
func f() {
var x int
x = 1
global = &x
}
func g() {
y := new(int)
*y = 1
}上述代碼中,函數(shù) f 里的變量 x 必須在堆上分配,因?yàn)樗诤瘮?shù)退出后依然可以通過包一級(jí)的 global 變量找到,雖然它是在函數(shù)內(nèi)部定義的。用Go語(yǔ)言的術(shù)語(yǔ)說,這個(gè)局部變量 x 從函數(shù) f 中逃逸了。
相反,當(dāng)函數(shù) g 返回時(shí),變量 *y 不再被使用,也就是說可以馬上被回收的。因此,*y 并沒有從函數(shù) g 中逃逸,編譯器可以選擇在棧上分配 *y 的存儲(chǔ)空間,也可以選擇在堆上分配,然后由Go語(yǔ)言的 GC(垃圾回收機(jī)制)回收這個(gè)變量的內(nèi)存空間。
在實(shí)際的開發(fā)中,并不需要刻意的實(shí)現(xiàn)變量的逃逸行為,因?yàn)樘右莸淖兞啃枰~外分配內(nèi)存,同時(shí)對(duì)性能的優(yōu)化可能會(huì)產(chǎn)生細(xì)微的影響。
雖然Go語(yǔ)言能夠幫助我們完成對(duì)內(nèi)存的分配和釋放,但是為了能夠開發(fā)出高性能的應(yīng)用我們?nèi)稳恍枰私庾兞康穆暶髦芷凇@?,如果將局部變量賦值給全局變量,將會(huì)阻止 GC 對(duì)這個(gè)局部變量的回收,導(dǎo)致不必要的內(nèi)存占用,從而影響程序的性能。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流