对于一个没有计算机科学背景的人来说,计算机科学界的lambda是什么?
当前回答
有点过于简单:lambda函数是一个可以传递给其他函数的函数,它的逻辑被访问。
在C#中,lambda语法通常以与匿名委托相同的方式编译为简单方法,但它也可以分解并读取其逻辑。
例如(在C#3中):
LinqToSqlContext.Where(
row => row.FieldName > 15 );
LinqToSql可以读取该函数(x>15)并将其转换为实际的SQL以使用表达式树执行。
上述声明变为:
select ... from [tablename]
where [FieldName] > 15 --this line was 'read' from the lambda function
这与普通方法或匿名委托不同(它们实际上只是编译器的魔法),因为它们无法读取。
并非C#中所有使用lambda语法的方法都可以编译为表达式树(即实际的lambda函数)。例如:
LinqToSqlContext.Where(
row => SomeComplexCheck( row.FieldName ) );
现在无法读取表达式树-无法分解SomeComplexCheck。SQL语句将在没有where的情况下执行,数据中的每一行都将通过SomeComplexCheck进行处理。
Lambda函数不应与匿名方法混淆。例如:
LinqToSqlContext.Where(
delegate ( DataRow row ) {
return row.FieldName > 15;
} );
这也有一个“内联”函数,但这一次它只是编译器的魔法——C#编译器会将其拆分为一个具有自动生成名称的新实例方法。
匿名方法不能被读取,因此逻辑不能像lambda函数那样被翻译出来。
其他回答
“lambda”这个名字只是一个历史产物。我们所谈论的只是一个表达式,其值是一个函数。
一个简单的例子(下一行使用Scala)是:
args.foreach(arg => println(arg))
其中foreach方法的参数是匿名函数的表达式。上面的一行与编写类似的代码大致相同(不是真正的代码,但你会明白的):
void printThat(Object that) {
println(that)
}
...
args.foreach(printThat)
除了你不需要麻烦:
在其他地方声明函数(稍后重新访问代码时必须查找它)。命名你只使用一次的东西。
一旦你习惯了函数值,就不得不不使用它们,就像需要命名每个表达式一样愚蠢,比如:
int tempVar = 2 * a + b
...
println(tempVar)
而不是只在需要的地方编写表达式:
println(2 * a + b)
确切的符号因语言而异;希腊语并不总是必需的!;-)
我喜欢这篇文章中对Lambdas的解释:LINQ的演变及其对C#设计的影响。这对我来说很有意义,因为它为Lambdas展示了一个真实的世界,并将其作为一个实际的例子。
他们的快速解释:Lambdas是将代码(函数)视为数据的一种方式。
Ruby中lambda的示例如下:
hello = lambda do
puts('Hello')
puts('I am inside a proc')
end
hello.call
将生成以下输出:
Hello
I am inside a proc
lambda演算是一种一致的替代数学理论。例如,在学校数学中,人们可以看到x+y=5与x−y=1配对。除了处理单个方程的方法外,还可以将这两个方程的信息放在一起,前提是交叉方程的替换是合乎逻辑的。Lambda演算编纂了进行这些替换的正确方法。
假设y=x−1是第二个方程的有效重排,这:λy=x–1表示用符号x−1代替符号y的函数。现在想象将λy应用于第一个方程中的每个项。如果项是y,则执行替换;否则什么都不做。如果你在纸上这样做,你会看到应用λy将如何使第一个方程可解。
这是一个没有任何计算机科学或编程的答案。
我能想到的最简单的编程示例来自http://en.wikipedia.org/wiki/Joy_(编程语言)#如何工作:
下面是如何在命令中定义平方函数编程语言(C):int平方(int x){返回x*x;}变量x是一个形式参数,由实际调用函数时要平方的值。在函数中语言(方案)将定义相同的功能:(定义正方形(λ(x)(*x x)))这在很多方面都不同,但它仍然使用形式参数x以相同的方式。
补充:http://imgur.com/a/XBHub
Lambda函数或小型匿名函数是一个自包含的功能块,可以在代码中传递和使用。Lambda在不同的编程语言中有不同的名称——Python和Kotlin中的Lambda,Swift中的闭包,或者C和Objective-C中的Block。虽然lambda在这些语言中的含义非常相似,但有时会有细微差别。
让我们看看Closure(Lambda)在Swift中的工作原理:
let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]
1.正则函数
func backward(_ n1: String, _ n2: String) -> Bool {
return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)
// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]
2.闭包表达式
reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in
return n1 > n2
})
3.内联闭包表达式
reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in
return n1 > n2
})
4.根据上下文推断类型
reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )
5.单表达式闭包的隐式返回
reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )
6.速记参数名称
reverseOrder = coffee.sorted(by: { $0 > $1 } )
// $0 and $1 are closure’s first and second String arguments.
7.操作员方法
reverseOrder = coffee.sorted(by: >)
// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]