Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
比较C#和Java中的lambda捕获_Java_C#_Lambda - Fatal编程技术网

比较C#和Java中的lambda捕获

比较C#和Java中的lambda捕获,java,c#,lambda,Java,C#,Lambda,给出C#代码: 在lambda之后,x的值受lambda操作的影响,因此,这相当于通过引用将参数传递给函数 让我们与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 +

给出C#代码:

在lambda之后,x的值受lambda操作的影响,因此,这相当于通过引用将参数传递给函数

让我们与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");
如果我将lambda更改为:

Inc next = () -> { return x+1; };
输出为:

Before lambda, x = 10
The successor of 10 is 11
After lambda,  x = 10
在lambda之后,x的值不受lambda操作的影响,因此,这相当于按值将参数传递给函数

阻止Java更改捕获的变量的技术原因是什么

我知道错误消息是怎么说的:

«从lambda表达式引用的局部变量必须是final或有效final»

但这对我来说还不够。这背后的技术原因是什么

如果Java允许lambda更改捕获的变量,会产生什么后果


谢谢。

Java和JVM不支持对局部变量的引用。编译器可以做的是将变量转换为引用,但它不能

e、 它可以像这样翻译你的代码

int[] x = { 10 };
IntSupplier next = () -> { return ++x[0]; };

System.out.println("Before lambda, x = " + x);
System.out.println("The successor of " + x + " is " + next.getAsInt()); // 
System.out.println("After lambda,  x = " + x + "\n");
如果你真的需要它,你可以自己修改代码


顺便说一句,函数式编程的关键特性之一是尽可能使用纯函数。纯功能没有副作用。虽然Java没有任何方法来强制执行纯函数,但似乎添加一种具有细微副作用的方法与添加函数构造并不一致。

我认为这与副作用无关,因为变量是由值捕获的,所以,在lambda中,我们有一个变量的副本。@ArnbjorgJohansen确切地说,您有一个变量的副本,这意味着您无法更新原始变量。为了防止您错误地认为更新副本会更新原始版本,语言设计者做出了伟大的决定,要求变量(有效地)
final
(不可变),这样您就不会犯错误六羟甲基三聚氰胺六甲醚。。。我想这就是“这背后的技术原因是什么?”的答案。@ArnbjorgJohansen状态的改变是一种副作用。
Before lambda, x = 10
The successor of 10 is 11
After lambda,  x = 10
int[] x = { 10 };
IntSupplier next = () -> { return ++x[0]; };

System.out.println("Before lambda, x = " + x);
System.out.println("The successor of " + x + " is " + next.getAsInt()); // 
System.out.println("After lambda,  x = " + x + "\n");