我对编程很新,在做很多阅读时,这个lambda的概念不断出现,但我很难理解它实际上是什么,如何实现它将使我的编程生活如此好多了。首先,什么是lambda,其次是如何实现?
感谢所有发帖的人。正如评论中提到的,这是重复的,但是这里有很多很棒的答案,我想为社区保留它们,所以我把它变成了一个社区帖子。以下是其他问题的链接:
答案 0 :(得分:12)
Lambda很难捕捉到,但是一旦你想象它们,你就无法理解为什么你之前没有得到它。
Lambda是普通的功能,唯一的区别是你没有给他们起个名字。
要理解这一点,首先必须知道,在创建函数时,代码将存储在内存中,只能由计算机知道。
所以当你做那样的事情时:
function Foo ()
{
/* your code here */
}
你真正做的是将名称“Foo”绑定到内存中代码的地址。
现在,还有另一种访问地址的方法:引用(和指针,但让我们跳过这些讨厌的人)
嗯,lambda函数是一个没有名称的函数,因此它只能通过它的引用进行访问。
创建lambda函数时,通常只计划使用一次。
一步一步的过程通常是:
最后,引用丢失了,因此函数会自动销毁。
典型的用例是回调函数。您在一行中声明,创建并传递函数,因此它很方便。
在Python中,您可以在列表推导中使用lambda:
/* create a list of functions */
function_list = [(lambda x : number_to_add + x) for number_to_add in range(0, 10) ]
在Javascript中,您通常会将一个函数传递给其他函数。 JQuery示例:
$("img").each(
/* here we pass a function without any name to the "each()" method */
function(i){ his.src = "test" i ".jpg"; }
);
有些语言,如Javascript或Lisp,大量使用 lambda表达式。它可能是出于文化原因,但函数式编程范式往往导致lambda-mania。
长长的lambda使代码难以阅读。这就是为什么有些语言会限制lambda的可能性,例如Python中不允许使用“if”语句。
Lambdas只是普通的功能。无论你使用哪一个,你都可以使用普通的功能。这只是编码风格的问题。
答案 1 :(得分:9)
lambda是函数的内联描述。它起源于函数式编程语言,并且支持类似于它的其他语言的数量正在增长。这个名字来源于一个名为Lambda演算的数学事物,它影响了函数式编程语言(如Lisp),lambdas的概念来自于它。
您的问题取决于您所谈论的编程语言。例如,在F#中,您可以使用fun x -> x * x
来表示
int myfunction(int x) { return x * x; }
在C#中,您可以使用x => x * x
来表示相同的功能。
如何使用它以及你可以用它做什么几乎取决于你正在使用的语言。
谈到C#,关于它们的好处是能够将它们解析为表达式树。 lambda表达式可以用作表达式中的代码,如委托(大致是函数指针)或数据。使用它们作为表达式树,使LINQ to SQL等库能够使用表达式创建SQL语句,以便提交给服务器并获得适当的结果。
答案 2 :(得分:6)
Lambda是一种创建匿名函数或闭包的方法。在命令式语言(和功能性语言)中,它等同于允许嵌套函数,其中内部函数可以访问封闭函数的局部变量和参数。它可以在关键字lambda
,fun
,fn
甚至\
下的函数式语言中找到;在Smalltalk中,它被称为块。它也可以在大多数脚本语言中找到,例如Perl,Python,Lua等。
关于没有 lambda的唯一语言
没有嵌套函数的语言,如标准C或图标
具有第二类嵌套函数的语言---函数可能无法从函数返回,存储在全局变量中或存储在堆分配的数据结构中。该语系包括Pascal及其Modula,Ada和CLU家族的后代。
Lambda对程序员和编译器编写者有重要意义:不再可能将所有局部变量存储在堆栈上。相反,某些变量可能捕获并存储在堆分配的闭包中。请注意当您编写lambda时,您正在编写分配。
示例:最简单的函数之一是组合(Haskell语法):
compose f g = \x -> f (g x)
这表示compose
将两个函数f
和g
作为参数,并返回一个匿名函数,该函数接受其参数x
,然后应用g
然后f
到x
。 compose
的应用程序在堆上创建一个闭包,它存储f
和g
的值以及指向该主体的代码的指针。拉姆达。在lambda常见的语言中,例如Haskell,ML,Caml和Scheme,已经花费了大量的精力使分配快速。一些脚本语言,例如Lua,具有不寻常的实现,这使得非lambda案例与命令式语言相同,同时也使lambda变得相当快。 Lambda在Smalltalk中也很快,它也设计用于在堆上分配大量对象。在lambda被改装的语言中,如Perl或Java(内部类与lambda相关),费用可能相对更高。
一般来说,如果一种语言设计时考虑了lambdas,你可以随意使用它们。特别是在ML,Caml,Scheme,Haskell,甚至匿名功能都很便宜 ---使用它们很多!
答案 3 :(得分:5)
lambda 意味着一个匿名函数,可以像其他常规变量一样传递和返回。所谓的函数式语言已经内置了,但最近有越来越多的语言支持它们,因为它们允许编写可重用的代码。例如,请参阅下一版C ++中编写的内容:
// write this once...
int transform_values(int * values, int n, function<int(int)> f) {
for(int i = 0; i < n; i++)
values[i] = f(values[i]);
}
int values[] = { 1, 2, 3, 4 };
// ... then call it to double the values in an array
transform_values(values, 4, [](int v) { return v * 2; });
在C#和支持lambdas的其他语言中看起来相似。现在有“封闭”这个词。这意味着lambda可以捕获局部变量并在计算结果时使用它们:
int local_variable = 5;
int values[] = { 1, 2, 3, 4 };
// ... then call it to multiply the values in an array
transform_values(values, 4, [=](int v) { return v * local_variable; });
变量local_variable
现在被捕获在闭包内,可以在其中使用。变量也可以通过闭包更新。 Lambdas是函数式语言的基本构建块。这是haskell的一个例子:
map (\x -> x * 2) [1, 2, 3, 4]
将与上面的C ++代码相同。它使用给定函数(此处为lambda)将列表中的值映射到结果列表中。使用haskell,您可以很好地看到所使用的语法如何映射到Lambda Calculus的数学概念。
答案 4 :(得分:2)
Lambda是lambda calculus,但我认为人们可以互换使用术语closure。见What is a Closure?
Ruby的实现很容易理解,也非常强大。在下面的代码中,times
方法接受大括号之间的代码块并将其调用回{{1}}次。您可以定义接受代码块并实现循环构造的类似方法。
HEIGHT
我想如果有一个参数会更有趣。
@cells = []
HEIGHT.times { @cells << empty_row }
答案 5 :(得分:2)
Lambda对不同的语言意味着不同的东西。我在python的上下文中了解它们,但我听说python的方法与其他语言不同。
基本上,在python中,lambda是一个匿名函数,它只能由一个表达式组成,其结果将被返回。
据我所知,在其他语言中,它们是更通用的匿名函数,没有单一的表达式限制,但我不确定细节。
匿名功能,听起来就像是这样。没有名字的功能。例如,它们经常被用作事件处理程序,或者您需要一个简单的回调函数但不想混淆命名空间的任何情况。