2

在命令式、面向对象的语言中,具有可变或不可变闭包是否更有意义?

例如:

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();

那么,拥有可变闭包或不可变闭包会更好,还是两者都有选择?不可变闭包似乎更容易实现,所以在这一点上,我想我会继续这样做,除非有充分的理由不这样做。

4

2 回答 2

4

命令式语言通常是围绕状态的概念构建的。因此,语言特性更有意义地反映这一点,包括闭包。是的,这种行为有时会令人困惑,但它是问题的一部分,也是在应用程序中拥有状态的优势。

我认为这个论点的最好证明是看看一些最近支持闭包的语言。C# 和 VB.Net,命令式 OO 语言,都选择了可变闭包。而 F#,一种函数式语言,具有不可变的闭包(主要源于 F# 默认情况下不可变的想法)。

另外,在命令式语言中具有不可变闭包实际上意味着什么?大多数人认为这是使变量等效于 C# 的只读。当然值类型会被保护不被修改,但是可变引用类型呢。您将无法更改变量指向的位置,但您可以调用变异函数并获得类似的效果。例如。

class Student {
  public string Name { get; set; }
}

void Example() {
  var student = new Student() { Name = "foo" };
  Action() del = () => 
    { student.Name = "bar"; };
  del();
}

这可以通过不可变闭包来实现,因为我实际上并没有修改变量指向的位置。但是,我显然仍在进行变异操作。

于 2009-04-04T19:42:27.400 回答
3

语言是否应该具有按值捕获或按引用捕获的 lambda?自己决定,但请参阅“关于 lambdas、捕获和可变性”以获得更多评论。

于 2009-04-04T19:47:09.683 回答