在命令式,对象定位语言中,拥有可变或不可变的闭包会更有意义吗?
例如:
int i=5;
function() f={print(i);};
f();
i=6;
f();
如果闭包是可变的,则会打印:
5
6
如果它是不可变的,则会打印:
5
5
我意识到即使使用不可变闭包,你仍然可以这样做:
class I {int i;}
I i=new I();
i.i=5;
function() f={
I j=i;
print(j.i);
};
f();
i.i=6;
f();
那么,拥有可变或不可变的闭包,或者两者都有选择会更好吗?不可变的闭包似乎更容易实现,所以在这一点上,我想我会继续使用它,除非有充分的理由不这样做。
答案 0 :(得分:4)
命令式语言通常围绕国家概念构建。因此,语言功能更有意义地反映这一点,包括闭包。是的,这种行为有时会令人困惑,但在应用程序中使用状态是问题和优势的一部分。
我认为这个论点的最好证明是看一些最近有闭包支持的语言。 C#和VB.Net,命令式OO语言都选择了可变闭包。虽然F#是一种函数式语言,但它具有不可变的闭包(主要源于F#默认是不可变的)。
在命令式语言中使用不可变闭包实际意味着什么呢?大多数人认为这使得变量等同于C#的readonly。确保值类型不受修改,但可变引用类型如何。您将无法更改变量指向的位置,但您可以调用变异函数并获得类似的效果。例如。
class Student {
public string Name { get; set; }
}
void Example() {
var student = new Student() { Name = "foo" };
Action() del = () =>
{ student.Name = "bar"; };
del();
}
这可以使用不可变闭包来实现,因为我实际上并没有修改变量指向的位置。但是我显然仍在进行变异操作。
答案 1 :(得分:3)
应该是语言有lambda是按值获取还是通过引用捕获?请自行决定,但请参阅“On lambdas, capture, and mutability”以获取更多评论。