Ion*_*tan 178
简单地说,lambda是一个没有名字的函数,或者是一个匿名函数.一小段可执行代码,可以传递,就像它是一个变量一样.在JavaScript中:
function () {}; // very simple
Run Code Online (Sandbox Code Playgroud)
现在让我们看看这些lambdas的一些用途.
Lambdas可用于抽象样板代码.例如循环.我们习惯整天写作for
和while
循环.但这是不编写的代码.我们可以在循环中提取代码,这是循环中最重要的部分,并抽象掉其余部分:
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,我们能够抽象出缓存/存储逻辑.如果对于另一个例子有一些解决方法,我相信使用其他技术很难解决这个特殊问题.我们设法将一些重要的样板代码提取到一个地方.更何况,我们摆脱了的users
和photos
全局变量.
查看您的个人资料,我发现您主要是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示例中,我使用了闭包来创建围绕store
param 的闭包.这样,即使在memoize
函数返回其结果(lambda)之后,我也可以访问该参数.
Chu*_*uck 19
术语"lambda"用于表示匿名函数,通常是闭包.它们很有用,因为它们允许您编写使用其他函数的函数,而不会不必要地膨胀您的代码.例如,在Ruby中:
(1..100).select {|num| num % 2 == 0}
Run Code Online (Sandbox Code Playgroud)
这将创建一个包含1到100之间偶数的数组.我们不必编写显式循环 - select方法接受一个用于测试值的函数,因此我们所需要的只是我们的自定义逻辑.这使我们可以在几乎没有任何努力或开销的情况下大大定制方法.基本上,我们可以用较小的函数组合函数.
这只是他们能做的一个简单的例子.将函数作为数据传递的能力非常强大,函数式语言程序员通常会用它来做一些非常棒的事情.
.NET中的Lambdas通常被称为"语法糖".它们不直接影响功能,但是它们使语言更易于人们使用.
当您了解使用它们的强大功能后,我相信您会发现与使用委托/匿名方法的旧式方式相比,您将编写更少的代码.
归档时间: |
|
查看次数: |
7106 次 |
最近记录: |