2017-03-04 17 views
-2

考慮下面的函數:閉包中去:在命名返回值不同的輸出

func main() { 
    var a int = 3 
    sum := func() {a = a*2} 
    sum() 
    sum() 
    fmt.Println(a) // returns 12 
} 

但是:

func main() { 
    var a int = 3 
    sum := func() (a int) {a = a*2; return} 
    sum() 
    sum() 
    fmt.Println(a) // returns 3 
} 

我不能完全理解這種行爲的邏輯:爲什麼它會回到老值aa = a*2

+3

*我不能完全理解這種行爲*邏輯:你遮蔽變量'了';這有什麼困惑? –

+0

@TimCooper:Go的返回值可以被命名。如果是這樣,他們被視爲在函數頂部定義的變量。「這說明問題。這不是意識形態的封閉行爲。 –

回答

0

像@TimCooper評論,你是陰影「a」。

如果您運行下面的代碼,您將看到兩個不同的內存地址。

這意味着是「2變量a」。

sum()中的「a」表示它自己的返回值,並且它沒有賦值,因此編譯器會將「零值」賦值給「其他a」,即數值類型爲0。

所以,A = A * 2爲等於0 = 0 * 2.

當總和()結束,則返回 「以外的」(記住不同的存儲器地址?),保持「第一一個「不變。

此鏈接可能會有所幫助: Go zero values

package main 

import "fmt" 

func main() { 
    var a int = 3 
    sum := func() (a int) { 
     fmt.Println(&a) // func sum() scope (a's copy memory address) 
     a = a * 2 
     return 
    } 
    b := sum()  // initializing b with the sum() return 
    fmt.Println(&a) // func main() scope (a's memory address) 
    fmt.Println(b) // func sum() return 
    fmt.Println(a) // old value, stills 3 
}