每个人都在说什么"Lambda"? [英] What is this 'Lambda' everyone keeps speaking of?

查看:54
本文介绍了每个人都在说什么"Lambda"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每个人都在谈论的"Lambda"是什么?很多人似乎都喜欢它,但是我可以从中收集到的只是一种将大量代码挤入一个表达式中的一种方法.

What is this 'Lambda' everyone keeps speaking of? A lot of people seem to love it, but all I can gather from it is it is just a way of cramming lots of lines of code into a single expression.

有人可以启发我了解它的真实价值吗?

Can someone please enlighten me on its true value?

推荐答案

无名称的功能

简而言之,lambda是一个没有名称的函数或一个匿名函数.一小段可执行代码,可以像可变变量一样传递.在JavaScript中:

Functions without a name

Simply put, a lambda is a function without a name, or an anonymous function. A small piece of executable code, that can be passed around as if it were a variable. In JavaScript:

function () {}; // very simple

现在让我们看看这些lambda的一些用法.

Let's see now some uses for these lambdas.

Lambda可以用于提取样板代码.例如循环.我们习惯于整天编写forwhile循环.但这是未编写的代码.我们可以将代码提取到循环中,这是循环中最重要的部分,然后将其余部分抽象化:

Lambdas may be used to abstract away boilerplate code. For example loops. We're used to write for and while loops all day long. But this is code that does not be written. We could extract the code inside the loop, the most important part of the loop, and abstract away the rest:

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

使用数组对象的 forEach ,变成:

by using the forEach of array objects, becomes:

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

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

The above abstraction may not be that useful, but there are other higher order functions, like forEach, that perform much more useful tasks. For example 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);

代码执行延迟

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

Code execution delay

In some environments, in which the concept of event is available, we could use lambdas to respond to events that may happen at some point in time.

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

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

这本可以通过其他方式完成的,但是这些方式非常冗长.例如,在Java中,有Runnable接口.

This could have been done in some other ways, but those are rather verbose. For example, in Java there's the Runnable interface.

到目前为止,我们仅使用lambda作为其语法糖功能.但是在某些情况下,lambda可能会更有用.例如,我们可能具有返回lambda的函数.假设我们有一个函数,希望将其返回值缓存起来.

Until this point, we only used lambdas for its syntactic sugar capabilities mostly. But there are situations where lambdas can be much more useful. For example we may have functions that return lambdas. Let's say we have a function that we want its return values to be cached.

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];
};

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

Later on, we may notice that we have a similar function:

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];
};

其中显然有一个模式,因此让我们对其进行抽象.让我们使用记忆化.

There's clearly a pattern in there, so let's abstract it away. Let's use 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
});

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

As you can see, by using lambdas, we were able to abstract away the caching/memoization logic. If for the other example there were some workarounds, I believe that this particular problem is hardly solved using other techniques. We managed to extract some important boilerplate code into a single place. Not to mention that we got rid of the users and photos global variables.

查看您的个人资料,我发现您主要是Python用户.对于上述模式,Python具有装饰器的概念.网上有很多修饰符示例.唯一的区别是,在Python中,您最有可能在该装饰器函数中具有 named 嵌套函数.原因是Python仅支持单表达式lambda.但是概念是相同的.

Looking at your profile I see that you're mostly a Python user. For the above pattern, Python has the concept of decorators. There are lots of example on the net for memoization decorators. The only difference is that in Python you most likely have a named nested function inside that decorator function. The reason being that Python only support single-expression lambdas. But the concept is the same.

作为Python lambda使用的示例.上面我们过滤了偶数的代码可以用Python表示,如下所示:

As an example of Python lambda use. The above code in which we filtered even numbers can be represented in Python like this:

filter(lambda x: x % 2 == 0, [1, 2, 3, 4])

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

Anyway, lambdas are not that powerful without closures. Closures is what makes the concept of lambdas so powerful. In my memoization example I have used closures to create a closure around the store param. This way, I have access to that param even after the memoize function has returned its result (a lambda).

这篇关于每个人都在说什么"Lambda"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆