每个人都在谈论这个'Lambda'是什么?

Jos*_*unt 92 lambda

每个人都在谈论这个'Lambda'是什么?很多人似乎都喜欢它,但我能从中收集到的只是将一大堆代码填入单个表达式的方式.

有人可以告诉我它的真正价值吗?

Ion*_*tan 178

没有名字的功能

简单地说,lambda是一个没有名字的函数,或者是一个匿名函数.一小段可执行代码,可以传递,就像它是一个变量一样.在JavaScript中:

function () {}; // very simple
Run Code Online (Sandbox Code Playgroud)

现在让我们看看这些lambdas的一些用途.

摘要样板代码

Lambdas可用于抽象样板代码.例如循环.我们习惯整天写作forwhile循环.但这是不编写的代码.我们可以在循环中提取代码,这是循环中最重要的部分,并抽象掉其余部分:

for (var i=0; i<array.length; i++) {
    // do what something useful with array[i]
}
Run Code Online (Sandbox Code Playgroud)

通过使用forEach数组对象,变为:

array.forEach(function (element, index) {
   // do something useful with element
   // element is the equivalent of array[i] from above
});
Run Code Online (Sandbox Code Playgroud)

上面的抽象可能没那么有用,但还有其他更高阶的函数,比如forEach执行更有用的任务.例如filter:

var numbers = [1, 2, 3, 4];
var even    = [];

// keep all even numbers from above array
for (var i=0; i<numbers.length; i++) {
    if (numbers[i] % 2 === 0) {
        even.push(numbers[i]);
    }
}

alert(even);

// Using the filter method
even = [1, 2, 3, 4].filter(function (number) {
    return number % 2 === 0;
});

alert(even);
Run Code Online (Sandbox Code Playgroud)

代码执行延迟

在某些环境中,事件的概念可用,我们可以使用lambdas来响应某些时间点可能发生的事件.

window.onload = function () {
    alert("Loaded");
};

window.setTimeout(function () {
    alert("Code executed after 2 seconds.");
}, 2000);
Run Code Online (Sandbox Code Playgroud)

这可以通过其他方式完成,但这些方法相当冗长.例如,在Java中有Runnable接口.

功能工厂

在此之前,我们大多只使用lambdas来表达其语法糖能力.但有些情况下,lambdas可能更有用.例如,我们可能有返回lambdas的函数.假设我们有一个函数,我们希望它的返回值被缓存.

var users = [];
var getUser = function (name) {
    if (! users[name]) {
        // expensive operations to get a user. Ajax for example
        users[name] = user_from_ajax;
    }

    return users[name];
};
Run Code Online (Sandbox Code Playgroud)

稍后,我们可能会注意到我们有类似的功能:

var photos = [];
var getPhoto = function (name) {
    if (! photo[name]) {
        // expensive operations to get a user. Ajax for example
        photos[name] = photo_from_ajax;
    }

    return photos[name];
};
Run Code Online (Sandbox Code Playgroud)

那里有明显的模式,所以让我们把它抽象出来.让我们使用memoization.

/**
 * @param {Array}     store Data structure in which we cache lambda's return values
 * @param {Function}  lambda
 * @return {Function} A function that caches the result of calling the lambda param
 */
var memoize = function (store, lambda) {
    // return a new lambda
    return function (name) {
        if (! store[name]) {
            // Execute the lambda and cache the result
            store[name] = lambda(name);
        }

        return store[name];
    };
};

var getUsers = memoize([], function (name) {
    // expensive operations to get a user. Ajax for example
});

var getPhotos = memoize([], function (name) {
    // expensive operations to get a photo. Ajax for example
});
Run Code Online (Sandbox Code Playgroud)

如您所见,通过使用lambdas,我们能够抽象出缓存/存储逻辑.如果对于另一个例子有一些解决方法,我相信使用其他技术很难解决这个特殊问题.我们设法将一些重要的样板代码提取到一个地方.更何况,我们摆脱了的usersphotos全局变量.

查看您的个人资料,我发现您主要是Python用户.对于上述模式,Python具有装饰器的概念.对于memoization装饰器,网上有很多例子.唯一的区别是在Python中你很可能在装饰器函数中有一个命名的嵌套函数.原因是Python只支持单表达式lambdas.但这个概念是一样的.

作为Python lambda使用的一个例子.我们过滤偶数的上述代码可以用Python表示如下:

filter(lambda x: x % 2 == 0, [1, 2, 3, 4])
Run Code Online (Sandbox Code Playgroud)

无论如何,如果没有封闭,lambdas就没有那么强大.闭包是使lambdas概念如此强大的原因.在我的memoization示例中,我使用了闭包来创建围绕storeparam 的闭包.这样,即使在memoize函数返回其结果(lambda)之后,我也可以访问该参数.

  • 哇,你花了很多时间. (3认同)
  • @ Mk12,在实际写的答案中,并非如此.学习这些东西,是的,自从我开始以来已经有一段时间了:) (3认同)

Chu*_*uck 19

术语"lambda"用于表示匿名函数,通常是闭包.它们很有用,因为它们允许您编写使用其他函数的函数,而不会不必要地膨胀您的代码.例如,在Ruby中:

(1..100).select {|num| num % 2 == 0}
Run Code Online (Sandbox Code Playgroud)

这将创建一个包含1到100之间偶数的数组.我们不必编写显式循环 - select方法接受一个用于测试值的函数,因此我们所需要的只是我们的自定义逻辑.这使我们可以在几乎没有任何努力或开销的情况下大大定制方法.基本上,我们可以用较小的函数组合函数.

这只是他们能做的一个简单的例子.将函数作为数据传递的能力非常强大,函数式语言程序员通常会用它来做一些非常棒的事情.

  • 也许你应该添加管道中的东西是参数.我是其中一个阅读红宝石的人之一. (6认同)

H_I*_*H_I 6

"Lambda"可能只是太少了.看看Lambda演算.它在函数式编程中很有用.

函数式编程是另一种编程范式(如过程式或面向对象).

  • 然后人们谈论"Lambda",很可能他们正在谈论匿名函数,函数指针,闭包或类似的东西.几乎从不参考真正的lambda演算事物. (4认同)

red*_*are 5

.NET中的Lambdas通常被称为"语法糖".它们不直接影响功能,但是它们使语言更易于人们使用.

当您了解使用它们的强大功能后,我相信您会发现与使用委托/匿名方法的旧式方式相比,您将编写更少的代码.

  • 这就是为什么我通过回答关于.net澄清的原因.如果其他人用他们的语言实现唧唧喳喳,那么无论他们的语言选择如何,q&a都会帮助很多人. (2认同)