对于一个没有计算机科学背景的人来说,计算机科学界的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函数那样被翻译出来。

其他回答

在CS的上下文中,lambda函数是一个抽象的数学概念,它解决了数学表达式的符号求值问题。在这种情况下,lambda函数与lambda项相同。

但在编程语言中,这是不同的。这是一段被宣布为“到位”的代码,可以作为“一流公民”传递。这个概念似乎很有用,因此它几乎进入了所有流行的现代编程语言(参见lambda函数everwhere post)。

它是一个没有名称的函数。例如,在c#中,您可以使用

numberCollection.GetMatchingItems<int>(number => number > 5);

返回大于5的数字。

number => number > 5

这里是lambda部分。它表示一个接受参数(数字)并返回布尔值(数字>5)的函数。GetMatchingItems方法对集合中的所有项使用此lambda并返回匹配项。

Ruby中lambda的示例如下:

hello = lambda do
    puts('Hello')
    puts('I am inside a proc')
end

hello.call

将生成以下输出:

Hello
I am inside a proc

例如,在Javascript中,函数被视为与其他所有类型(int、string、float、bool)相同的混合类型。因此,您可以动态创建函数,将它们分配给对象,然后稍后再调用它们。它是有用的,但不是你想过度使用的东西,否则你会让所有在你之后必须维护代码的人感到困惑。。。

这是我玩的一些代码,看看这个兔子洞有多深:

var x = new Object;
x.thingy = new Array();
x.thingy[0] = function(){ return function(){ return function(){ alert('index 0 pressed'); }; }; }
x.thingy[1] = function(){ return function(){ return function(){ alert('index 1 pressed'); }; }; }
x.thingy[2] = function(){ return function(){ return function(){ alert('index 2 pressed'); }; }; }

for(var i=0 ;i<3; i++)
    x.thingy[i]()()();

lambda是一种内联定义的函数类型。除了lambda之外,通常还有某种类型的变量类型,可以保存对函数lambda或其他函数的引用。

例如,这里有一段不使用lambda的C#代码:

public Int32 Add(Int32 a, Int32 b)
{
    return a + b;
}

public Int32 Sub(Int32 a, Int32 b)
{
    return a - b;
}

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, Add);
    Calculator(10, 23, Sub);
}

这调用Calculator,不仅传递两个数字,还传递要在Calculator中调用的方法以获得计算结果。

在C#2.0中,我们得到了匿名方法,这将上述代码缩短为:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a + b;
    });
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a - b;
    });
}

然后在C#3.0中,我们得到了lambdas,这使得代码更短:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, (a, b) => a + b);
    Calculator(10, 23, (a, b) => a - b);
}