mirror of
				https://github.com/gopl-zh/gopl-zh.github.com.git
				synced 2025-11-03 19:31:35 +00:00 
			
		
		
		
	Fixes #205
This commit is contained in:
		@@ -14,10 +14,14 @@ fmt.Println(*p) // "2"
 | 
			
		||||
下面的兩個newInt函數有着相同的行爲:
 | 
			
		||||
 | 
			
		||||
```Go
 | 
			
		||||
func newInt() *int {                func newInt() *int {
 | 
			
		||||
	return new(int)                     var dummy int
 | 
			
		||||
}                                       return &dummy
 | 
			
		||||
                                    }
 | 
			
		||||
func newInt() *int {
 | 
			
		||||
	return new(int)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newInt() *int {
 | 
			
		||||
	var dummy int
 | 
			
		||||
	return &dummy
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
每次調用new函數都是返迴一個新的變量的地址,因此下面兩個地址是不同的:
 | 
			
		||||
 
 | 
			
		||||
@@ -37,14 +37,19 @@ for t := 0.0; t < cycles*2*math.Pi; t += res {
 | 
			
		||||
```Go
 | 
			
		||||
var global *int
 | 
			
		||||
 | 
			
		||||
func f() {                 func g() {
 | 
			
		||||
	var x int                  y := new(int)
 | 
			
		||||
	x = 1                      *y = 1
 | 
			
		||||
	global = &x            }
 | 
			
		||||
func f() {
 | 
			
		||||
	var x int
 | 
			
		||||
	x = 1
 | 
			
		||||
	global = &x
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func g() {
 | 
			
		||||
	y := new(int)
 | 
			
		||||
	*y = 1
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
這里的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語言的自動垃圾收集器對編寫正確的代碼是一個鉅大的幫助,但也併不是説你完全不用考慮內存了。你雖然不需要顯式地分配和釋放內存,但是要編寫高效的程序你依然需要了解變量的生命週期。例如,如果將指向短生命週期對象的指針保存到具有長生命週期的對象中,特别是保存到全局變量時,會阻止對短生命週期對象的垃圾迴收(從而可能影響程序的性能)。
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user