2016-03-22 27 views
1

看到測試代碼:golang關閉(匿名函數)抓錯parameter`s值

package main 

import "fmt" 

func main() { 
    i := 10 

    closure1 := func() { 
     fmt.Printf("closure, i: %d\n", i) 
     i = 15 
    } 

    closure1() 

    fmt.Printf("in main, i: %d\n", i) 

    closure2 := func(x int) { 
     fmt.Printf("function call, pass parameter, i: %d\n", x) 
    } 

    i = 20 

    closure1() 
    closure2(i) 
} 

我覺得closure2的輸出應該是20,但實際結果是15,我不知道爲什麼? ??? 有人可以幫助我,請在我的代碼中看到我的評論,提前致謝。

+1

''''''''在'closure1'結尾分配了15個,你在調用'closure2'之前調用。所以你通過15'clos2' –

+0

[陷阱與閉合在去](http://www.goinggo.net/2014/06/pitfalls-with-closures-in-go.html) –

+0

我看到,golang關閉catch對i的引用,而不是快照值,我明白了,非常感謝。 – scott

回答

1

的問題是,你的第一個分配我到15時,您的呼叫closure1()然後封你們兩個打印..你做closure1()後分配1至20 ..那是問題,這應該解決您的問題:

package main 

import "fmt" 

func main() { 
    i := 10 

    closure1 := func() { 
     fmt.Printf("closure, i: %d\n", i) 
     i = 15 
    } 

    closure1() 

    fmt.Printf("in main, i: %d\n", i) 

    closure2 := func(x int) { 
     fmt.Printf("function call, pass parameter, i: %d\n", x) 
    } 



    closure1() 
    i = 20 // Now it assigns it back to 20.. So the result below will become 20... 
    closure2(i) 
} 

你看到你的問題了嗎?

+0

是的,在本質上,\t golang關閉捕獲一個參考我,而不是一個快照值,我明白了,再次感謝約翰和dsafds,「\t 陷阱與閉合在圍棋」是很好的學習材料。 – scott

0

closure1的最後一行將i設置爲15.這個我屬於main()上下文。

接下來最後一行主要調用closure1()了。所以我從main重新設置爲15。