有人能解释一下吗?我理解它们背后的基本概念,但我经常看到它们互换使用,我感到困惑。

现在我们到了这里,它们和普通函数有什么不同?


当前回答

简单地说,闭包是一个关于作用域的技巧,lambda是一个匿名函数。我们可以用lambda更优雅地实现闭包,lambda经常被用作传递给更高函数的参数

其他回答

这个问题已经12年了,我们仍然把它作为谷歌中“闭包vs lambda”的第一个链接。 所以我不得不说,因为没有人明确地说过。

Lambda表达式是一个匿名函数(声明)。

一个闭包,引用Scott的《编程语言语用学》解释为:

创建引用环境的显式表示(通常是当前调用子例程时执行的环境),并将其与子例程的引用捆绑在一起,称为闭包。

也就是说,它就像我们所说的“函数+投降上下文”的捆绑。

它取决于函数是否使用外部变量来执行操作。

外部变量——定义在函数作用域之外的变量。

Lambda表达式是无状态的,因为它依赖于参数、内部变量或常量来执行操作。 函数<Integer,Integer> lambda = t -> { Int n = 2 返回t * n } 闭包保持状态,因为它使用外部变量(即函数体范围之外定义的变量)以及参数和常量来执行操作。 Int n = 2 函数<Integer,Integer>闭包= t -> { 返回t * n }

当Java创建闭包时,它将变量n与函数一起保存,以便在传递给其他函数或在任何地方使用时可以引用它。

闭包意味着一个函数返回另一个函数。不是结果,而是像委托一样的可调用函数。 Lambda是一个匿名函数描述。如果lambda返回一个函数,它也可以是一个闭包。

Lambda表达式只是一个匿名函数。例如,在纯java中,你可以这样写:

Function<Person, Job> mapPersonToJob = new Function<Person, Job>() {
    public Job apply(Person person) {
        Job job = new Job(person.getPersonId(), person.getJobDescription());
        return job;
    }
};

其中Function类是在java代码中构建的。现在你可以在某处调用mapPersonToJob.apply(person)来使用它。这只是一个例子。在没有语法之前,这是一个lambda。lambda是一个捷径。

关闭:

当Lambda可以访问此作用域之外的变量时,它就成为闭包。我猜你可以说它的魔力,它神奇地包裹着它被创建的环境,并使用其作用域之外的变量。因此,闭包意味着lambda可以访问它的OUTER SCOPE。

在Kotlin中,lambda总是可以访问它的闭包(在它的外部作用域中的变量)

lambda只是一个匿名函数——一个没有名字定义的函数。在Scheme等某些语言中,它们等同于命名函数。实际上,函数定义在内部被重写为将lambda绑定到变量。在其他语言中,如Python,它们之间有一些(相当不必要的)区别,但它们在其他方面的行为是相同的。

闭包是在定义它的环境上关闭的任何函数。这意味着它可以访问不在其参数列表中的变量。例子:

def func(): return h
def anotherfunc(h):
   return func()

这将导致一个错误,因为func不会在另一个环境中关闭func - h是undefined。Func只在全局环境下关闭。这是可行的:

def anotherfunc(h):
    def func(): return h
    return func()

因为这里,func是在anotherfunc中定义的,而在python 2.3及以上版本(或类似这样的数字)中,当他们几乎正确地获得闭包时(突变仍然无效),这意味着它在anotherfunc的环境中关闭,并可以访问其中的变量。在Python 3.1+中,使用nonlocal关键字时也可以使用突变。

还有一点很重要——func将继续在另一个func的环境中关闭,即使它不再在另一个func中被求值。这段代码也可以工作:

def anotherfunc(h):
    def func(): return h
    return func

print anotherfunc(10)()

这将输出10。

正如您所注意到的,这与lambda无关——它们是两个不同(尽管相关)的概念。