“close over”是什么意思?(问题标题)

30

我正在努力理解闭包,但每个我能找到的关于闭包的定义都使用相同的晦涩和模糊的短语:“closes over(闭合)”。

什么是闭包?“哦,它是一个函数,closes over(闭合)另一个函数。”

但我找不到任何关于“closes over”(闭合)的定义。有人能解释一下“Thing A close over Thing B”是什么意思吗?


闭包“关闭”开放绑定。这是一个起点:http://en.wikipedia.org/wiki/Closure_%28computer_programming%29#History_and_etymology - Blorgbeard
3
“闭包是指关闭开放绑定的东西。”这个描述能再更简略一些吗?真的吗?真的吗?! - smeeb
如果那是我说过或链接到的直接引用,你就有一定的观点。这是我链接到的内容:“一个 lambda 表达式,其开放绑定(自由变量)已被词法环境关闭或绑定,从而产生一个闭合表达式或闭包”。 - Blorgbeard
1
这里的“closed”一词源于数理逻辑... 相关概念包括“表达式”,“自由变量”,“约束变量”和“闭项”。 例如,请参见http://en.wikipedia.org/wiki/Free_variables_and_bound_variables - Nemo
2个回答

14

闭包是一个由代码指针和环境指针组成的对。环境指针包含了给定函数中的所有自由变量。例如:

fun f(a, b) = 
  let fun g(c, d) = a + b + c + d
  in g end

val g = f(1, 2)
val result = g(3, 4)  (*should be 10*)

函数g包含两个自由变量:ab。如果您不熟悉自由变量这个术语,它是指在函数范围内未定义的变量。在这种情况下,闭包意味着从函数中删除任何自由变量。上面的例子为闭包提供了很好的动机。当函数f返回时,我们需要能够记住稍后使用的ab的值。编译方式是将函数g处理成一个代码指针和一个包含所有自由变量的记录,例如:

 fun g(c, d, env) = env.a + env.b + c + d
 fun f(a, b, env) = (g, {a = a, b = b})
 val (g, gEnv) = f(1, 2)
 val result = g(3, 4, gEnv)

当我们应用函数g时,我们提供了调用函数f时返回的环境。请注意,现在函数g不再有任何未在其作用域中定义的变量。通常称不包含任何自由变量的术语为闭合。如果您仍不清楚,Matt Might 在http://matt.might.net/articles/closure-conversion/上有一个非常深入的闭包转换解释。

Javascript中相同的示例

在闭包转换之前

function f(a, b){
    function g(c, d) {
        return a + b + c + d
    }
    return g
}

var g = f(1, 2)
var result = g(3, 4)

进行闭包转换后:

function g(c, d, env) {
    return env.a + env.b + c + d
}

function f(a, b, env) {
    return [g, {"a": a, "b": b}]
}

var [g, gEnv] = f(1, 2)
var result = g(3, 4, gEnv)

йҡҫйҒ“дёҚеә”иҜҘжҳҜпјҡеҮҪж•°gеҢ…еҗ«дёӨдёӘиҮӘз”ұеҸҳйҮҸпјҡaе’Ңbеҗ—пјҹдҪ еҲҡжүҚиҜҙиҝҮпјҢиҮӘз”ұеҸҳйҮҸжҳҜжҢҮеңЁдҪңз”Ёеҹҹдёӯ__жІЎжңү__е®ҡд№үзҡ„еҸҳйҮҸпјҹ - Sehnsucht
是的,抱歉那是个打错字。谢谢! - Matt
@NatalieCardot,在函数g的主体内,参数ab既没有作为参数传递,也没有在本地定义。这很符合Udacity的定义。 - Matt
解释很好,但是例子让我感到困惑。我不知道使用的是什么编程语言,是否可以添加类似的JavaScript代码示例?特别是 fun f(a, b, env) = (g, {a = a, b = b}),对我来说毫无意义,也是最令人困惑的部分。有一个JS等效版本将有助于减轻语言的细节,并使该答案更容易被更多人理解。 - Vadorequest
在JS片段“Before closure conversion”中,我会说函数g封闭了变量ab。这种用法与How do JavaScript closures work?中的用法一致。这个回答是否在说,在“Before closure conversion”片段中没有封闭任何内容,但是在“After closure conversion”片段中却有封闭的内容?能否请澄清一下这个问题? - Sebastian Simon
pythontutor上逐步运行JavaScript代码让我对代码的工作原理有了深刻的认识。 - Mohammad Reza Khahani

9

来自苹果文档

闭包是一种自包含的功能块,可以在代码中传递和使用。Swift 中的闭包类似于 C 和 Objective-C 中的块以及其他编程语言中的 Lambda 表达式。

但这意味着什么?

这意味着一个闭包可以捕获定义它的上下文中的变量和常量,并引用这些变量和常量,称为闭合这些变量和常量。

希望这有所帮助!


我可以说“闭包是没有自由变量的函数”吗?或者这样说不正确?从您的回答中我了解到,这可能是一个很好的定义。 - Vadorequest
1
@Vadorequest,我认为所谓的“闭合函数”是指没有自由变量的函数。而“闭包”则是指具有自由变量的函数,并且该函数在函数外部被赋予了一个环境,使得这些自由变量被绑定到特定的值上,从而使得该函数针对这些变量变成了一个“已关闭”的状态。 - MetaEd
谢谢!阅读http://matt.might.net/articles/closure-conversion/也帮助我更好地理解它。 - Vadorequest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接