我们可以拥有没有内部功能的闭包吗?

时间:2012-06-12 05:45:00

标签: closures

闭包是一个外部函数O,它在其体内有一个变量x和一个内部函数F.F必须访问x。 O必须返回F,即F本身(或其指针),而不是F的返回值。这样,因为F可以从O外部的代码调用,而F需要执行x,所以x必须保留在范围之后O退出。

在javascript中我们可以定义函数内的函数,因此它是直截了当的。在C#中,我们必须使用匿名方法或匿名委托来与内部函数具有相同的行为。

闭包的本质是在函数退出后保留函数的局部变量的值,以便下次调用函数时,先前的值已经存在。上面提到的语法和技术是完成闭包的方法。

无论如何,使用任何语言(汇编语言除外)都可以在不使用内部函数或委托的情况下获得闭包的本质。 OOP中的课程中的课程字段具有相同的效果,但我正在寻找除此之外的方法。

2 个答案:

答案 0 :(得分:1)

根据定义,闭包关闭其词法范围中的变量。如果它不能通过局部变量“内在”其他东西,那将完全没用。因此,闭包必须能够在某个函数内部。

然而,一个复杂性是某些语言中的闭包与匿名函数密切相关。 (匿名函数通常必须是闭包;闭包不一定是匿名函数,但在某些语言中,唯一的闭包是匿名函数。)匿名函数的语法可能与常规(命名)函数的语法不同(特别是在语言中)函数和变量的单独命名空间;命名函数将在函数命名空间中,但匿名函数将是数据)。在某些语言中,没有“内部”命名函数。

例如,在PHP中,所有命名函数都在全局范围内。将命名函数定义放在另一个函数定义中(违反直觉)定义了外部函数运行时全局作用域中的内部函数(外部代码可以看到它)(好像它在外部作用域中声明,但是被延迟)。但是,PHP 5.3+也有匿名函数,它们是闭包;人们通常将匿名函数称为“闭包”,因为它们是该语言中唯一的闭包。

另一个例子是Ruby。 def语法定义了一种方法。在另一个方法中定义一个方法(违反直觉)仍然将该方法定义为对其他方法可见。 Ruby也使用lambdaprocProc.new语法来创建闭包的匿名函数,但这些函数在语法上是不同的。

答案 1 :(得分:0)

我不会将它们称为闭包,但保留状态的局部变量的概念是在VB中使用Static局部变量。

Sub Example()
  Dim normalVar As Integer
  Static staticVar As Integer

  normalVar += 1
  staticVar += 1

  Console.WriteLine("{0} {1}", normalVar, staticVar)
End Sub

(这是VB.NET但Static在VB3或更早版本中。)

这将输出

1 1
1 2
1 3

如果被叫三次。