回到简体

This commit is contained in:
chai2010
2016-02-15 11:06:34 +08:00
parent 9e878f9944
commit 2b37b23285
177 changed files with 2354 additions and 2354 deletions

View File

@@ -1,8 +1,8 @@
### 2.3.4. 量的生命
### 2.3.4. 量的生命
量的生命期指的是在程序行期間變量有效存在的時間間隔。對於在包一級聲明的變量來説,它的生命期和整程序的運行週期是一致的。而相比之下,在局部量的聲明週期則是動態的:每次建一個新變量的聲明語句開始,直到該變量不再被引用止,然後變量的存儲空間可能被收。函數的參數變量和返迴值變量都是局部量。它在函每次被調用的時候創建。
量的生命期指的是在程序行期间变量有效存在的时间间隔。对于在包一级声明的变量来说,它的生命期和整程序的运行周期是一致的。而相比之下,在局部量的声明周期则是动态的:每次建一个新变量的声明语句开始,直到该变量不再被引用止,然后变量的存储空间可能被收。函数的参数变量和返回值变量都是局部量。它在函每次被用的时候创建。
例如,下面是1.4的Lissajous程序摘的代片段:
例如,下面是1.4的Lissajous程序摘的代片段:
```Go
for t := 0.0; t < cycles*2*math.Pi; t += res {
@@ -13,7 +13,7 @@ for t := 0.0; t < cycles*2*math.Pi; t += res {
}
```
譯註:函的有右小括弧也可以另起一行縮進,同時爲了防止編譯器在行尾自插入分號而導致的編譯錯誤,可以在末尾的參數變量後面顯式插入逗。像下面這樣
译注:函的有右小括弧也可以另起一行缩进,同时为了防止编译器在行尾自插入分号而导致的编译错误,可以在末尾的参数变量后面显式插入逗。像下面这样
```Go
for t := 0.0; t < cycles*2*math.Pi; t += res {
@@ -21,18 +21,18 @@ for t := 0.0; t < cycles*2*math.Pi; t += res {
y := math.Sin(t*freq + phase)
img.SetColorIndex(
size+int(x*size+0.5), size+int(y*size+0.5),
blackIndex, // 最插入的逗號不會導致編譯錯誤,這是Go編譯器的一特性
) // 小括弧另起一行縮進,和大括弧的格保存一致
blackIndex, // 最插入的逗号不会导致编译错误,这是Go编译器的一特性
) // 小括弧另起一行缩进,和大括弧的格保存一致
}
```
在每次循環的開始會創建臨時變量t在每次循迭代中創建臨時變量x和y。
在每次循环的开始会创建临时变量t在每次循迭代中创建临时变量x和y。
垃Go言的自圾收集器是如何知道一個變量是何可以被收的呢?里我可以避完整的技術細節,基本的實現思路是,從每個包級的變量和每個當前運行函的每一局部變量開始,通過指針或引用的訪問路徑遍歷,是否可以找到該變量。如果不存在這樣的訪問路徑,那麽説明該變量是不可的,也就是它是否存在併不會影響程序後續的計算結果。
垃Go言的自圾收集器是如何知道一个变量是何可以被收的呢?里我可以避完整的技术细节,基本的实现思路是,从每个包级的变量和每个当前运行函的每一局部变量开始,通过指针或引用的访问路径遍历,是否可以找到该变量。如果不存在这样的访问路径,那么说明该变量是不可的,也就是它是否存在并不会影响程序后续的计算结果。
爲一個變量的有效週期隻取決於是否可,因此一個循環迭代部的局部量的生命期可能超出其局部作用域。同,局部量可能在函數返迴之後依然存在。
为一个变量的有效周期只取决于是否可,因此一个循环迭代部的局部量的生命期可能超出其局部作用域。同,局部量可能在函数返回之后依然存在。
編譯器會自動選擇在棧上還是在堆上分配局部量的存儲空間,但可能令人驚訝的是,這個選擇併不是由用var是new聲明變量的方式定的。
编译器会自动选择在栈上还是在堆上分配局部量的存储空间,但可能令人惊讶的是,这个选择并不是由用var是new声明变量的方式定的。
```Go
var global *int
@@ -49,9 +49,9 @@ func g() {
}
```
f函里的x量必在堆上分配,因它在函退出依然可以通包一的global量找到,然它是在函數內部定用Go言的術語説這個x局部變量從函數f中逃逸了。相反g函數返迴時,變`*y`是不可的,也就是可以上被收的。因此,`*y`併沒有從函數g中逃逸編譯器可以選擇在棧上分配`*y`的存儲空間(譯註:也可以選擇在堆上分配,然由Go言的GC迴收這個變量的存空雖然這里用的是new方式。其在任何候,你不需爲了編寫正確的代而要考慮變量的逃逸行,要住的是,逃逸的量需要外分配存,同時對性能的化可能會産生細微的影
f函里的x量必在堆上分配,因它在函退出依然可以通包一的global量找到,然它是在函数内部定用Go言的术语说这个x局部变量从函数f中逃逸了。相反g函数返回时,变`*y`是不可的,也就是可以上被收的。因此,`*y`并没有从函数g中逃逸编译器可以选择在栈上分配`*y`的存储空间(译注:也可以选择在堆上分配,然由Go言的GC回收这个变量的存空虽然这里用的是new方式。其在任何候,你不需为了编写正确的代而要考虑变量的逃逸行,要住的是,逃逸的量需要外分配存,同时对性能的化可能会产生细微的影
Go言的自垃圾收集器對編寫正確的代是一個鉅大的助,但也不是你完全不用考慮內存了。你然不需要式地分配和釋放內存,但是要編寫高效的程序你依然需要了解量的生命期。例如,如果指向短生命週期對象的指保存到具有生命期的象中,特别是保存到全局變量時,會阻止短生命週期對象的垃圾收(而可能影程序的性能)。
Go言的自垃圾收集器对编写正确的代是一个巨大的助,但也不是你完全不用考虑内存了。你然不需要式地分配和释放内存,但是要编写高效的程序你依然需要了解量的生命期。例如,如果指向短生命周期对象的指保存到具有生命期的象中,特别是保存到全局变量时,会阻止短生命周期对象的垃圾收(而可能影程序的性能)。