Java 8 lambda范围问题 intx=1; 消费者f=(i)->{ int x=1;//无效 };
vsJava 8 lambda范围问题 intx=1; 消费者f=(i)->{ int x=1;//无效 };,java,closures,java-8,Java,Closures,Java 8,vs 消费者f=(i)->{ int x=1; }; int x=1;//有效的 想象一下一个方法中的这两个块。为什么第二个块有效?在第一个块中,您是“原始x变量”。通过创建新的x,您将无法再访问第一个x 第二个块没有问题,因为第二个x是在第一个x不再存在(超出范围)的时刻创建的 基本上:在第一种情况下,您试图同时拥有两个名为x的变量。在第二种情况下,您将在两个变量之后创建两个x变量:它们的生存期不会重叠。这与普通Java作用域非常相似: Consumer<Object>
消费者f=(i)->{
int x=1;
};
int x=1;//有效的
想象一下一个方法中的这两个块。为什么第二个块有效?在第一个块中,您是“原始
x
变量”。通过创建新的x
,您将无法再访问第一个x
第二个块没有问题,因为第二个x
是在第一个x
不再存在(超出范围)的时刻创建的
基本上:在第一种情况下,您试图同时拥有两个名为
x
的变量。在第二种情况下,您将在两个变量之后创建两个x
变量:它们的生存期不会重叠。这与普通Java作用域非常相似:
Consumer<Object> f = (i) -> {
int x = 1;
};
int x = 1; // valid
vs
那么为什么“范围”不是对称的呢。若lambda是如此透明,那个么它应该是对称的,但作用域根本不是对称的。甚至对于像
for
循环或if
statements.lol这样的构造也不一样,所以lambda(好像块等)不创建命名范围,而是创建生存期范围?为什么?当然,允许在内部作用域中重新定义(如“隐藏”)变量是一种完全合法的设计。再说一遍,这只是语言设计。但它带来了一定程度的混乱(根据作用域的不同处理同名变量和不同的值),没有实际的好处(仅仅使用不同的名称就足够容易了)。+1。这与兰博达斯无关;e、 匿名类将施加相同的约束。我将要写完全相同的东西!
Consumer<Object> f = (i) -> {
int x = 1;
};
int x = 1; // valid
int i;
{
int i; // invalid
}
{
int i; // valid
}
int i;