-2
給了C#代碼:比較拉姆達捕獲C#和Java
int x = 10;
Func<int> next =() => { return ++x; };
Console.WriteLine("Before lambda, x = {0}", x);
Console.WriteLine("The successor of {0} is {1}", x, next());
Console.WriteLine("After lambda, x = {0} \n", x);
輸出是:
Before lambda, x = 10
The successor of 10 is 11
After lambda, x = 11
拉姆達後,x的值是受拉姆達行動的話,這相當於通過引用將參數傳遞給函數。
讓我們與Java比較:
interface Inc
{
int Increment();
}
int x = 10;
Inc next =() -> { return ++x; };
System.out.println("Before lambda, x = " + x);
System.out.println("The successor of " + x + " is " + next.Increment()); // ERROR: local variables referenced from a lambda expression must be final or effectively final
System.out.println("After lambda, x = " + x + "\n");
如果我改變拉姆達這樣:
Inc next =() -> { return x+1; };
輸出是:
Before lambda, x = 10
The successor of 10 is 11
After lambda, x = 10
拉姆達後,x的值不受lambda動作的影響,所以這相當於通過值將參數傳遞給函數。
阻止Java更改捕獲的變量的技術原因是什麼?
我知道錯誤消息說的話:
«從lambda表達式中引用的局部變量必須是最後的或有效的最後»
但這是不夠的我。這背後的技術原因是什麼?
如果Java允許捕獲的變量可能被lambda更改,結果會是什麼?
謝謝。
我認爲這與副作用無關,因爲變量是由值捕獲的,所以在lambda裏面我們有一個變量的副本。 –
@ArnbjorgJohansen準確地說,你有一個*副本*的變量,這意味着你不能更新原件。爲了防止你錯誤地認爲更新副本會更新原文,語言設計者做出了一個偉大的決定,要求變量被*(有效)* final(不可變),所以你不能*犯這個錯誤。 ---嗯......我想這就是答案*「這背後的技術原因是什麼?」* – Andreas
@ArnbjorgJohansen狀態的變化是一個副作用。 –