lambda(或closure)封装函数指针和变量.这就是为什么在C#中,您可以执行以下操作:
int lessThan = 100;
Func<int, bool> lessThanTest = delegate(int i) {
return i < lessThan;
};
我在那里使用了一个匿名委托作为闭包(与lambda等效项相比,它的语法更清晰、更接近于C),它将less Than(堆栈变量)捕获到闭包中.在计算闭包时,将继续引用less Than(其堆栈帧可能已被销毁).如果我更改less Than,则更改比较:
int lessThan = 100;
Func<int, bool> lessThanTest = delegate(int i) {
return i < lessThan;
};
lessThanTest(99); // returns true
lessThan = 10;
lessThanTest(99); // returns false
在C中,这是非法的:
BOOL (*lessThanTest)(int);
int lessThan = 100;
lessThanTest = &LessThan;
BOOL LessThan(int i) {
return i < lessThan; // compile error - lessThan is not in scope
}
虽然我可以定义一个包含两个参数的函数指针:
int lessThan = 100;
BOOL (*lessThanTest)(int, int);
lessThanTest = &LessThan;
lessThanTest(99, lessThan); // returns true
lessThan = 10;
lessThanTest(100, lessThan); // returns false
BOOL LessThan(int i, int lessThan) {
return i < lessThan;
}
但是,现在我必须在计算它时传递这两个参数.如果我希望将这个函数指针传递给lessThan不在作用域中的另一个函数,我要么将其传递给链中的每个函数,要么将其升级为全局函数,从而手动使其保持活动状态.
尽管大多数支持闭包的主流语言都使用匿名函数,但这并没有要求.可以使用不带匿名函数的闭包,也可以使用不带闭包的匿名函数.
摘要:闭包是函数指针+捕获变量的组合.