2010-09-10 77 views
2

我認爲這是一個新手問題,但爲什麼它在最後的斷言失敗? 我在想這個閉包綁定了它的值,所以從閉包中改變它會改變閉包之外的值。Groovy - 閉包和綁定,爲什麼這段代碼不起作用?

def value = 5 

def foo(n){ 

    return { 

    ++n 

    } 
} 

def test = foo(value) 

assert test() == 6 
assert test() == 7 

assert value == 7 

感謝您的幫助。

回答

2

這似乎確實是一種奇怪的行爲,但我認爲這是正確的。所有對象的事件整數都通過引用傳遞。調用foo(value)將值傳遞給函數。變量'n'是與'value'引用相同的對象的引用。基本上你有兩個指向同一個對象的指針。當你增加'n'時,你只會增加這個變量。

因爲Integer類是不可變++ n實際正在做這樣的事情:

n = n + 1 

這是分配增加的值的變量n。頂部聲明的變量「值」仍然指向原始對象5.

1

請記住,Integer(運行時類型value)是不可變的。因此,雖然nvalue最初是指同一個對象,但當您執行++n時,它會創建一個新的Integervalue引用未更新爲引用此新對象,因此在執行完成時它仍然指的是初始對象(5)。

0

您正在爲名稱n分配一個新值,該名稱與名稱value不同。通過使value成爲可變對象,可以獲得所需的行爲。然後你可以改變它,而不是創建和分配一個新的對象。

這裏有一個簡單的例子,在列表中包裝值:

def value = [5] 

def foo(n){ 

    return { 

     n[0]++ 
     n 
    } 
} 

def test = foo(value) 

assert test() == [6] 
assert test() == [7] 

assert value == [7] 
相關問題