函数指针、闭包和 Lambda [英] Function pointers, Closures, and Lambda

查看:14
本文介绍了函数指针、闭包和 Lambda的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚在学习函数指针,当我阅读有关该主题的 K&R 章节时,我的第一反应是,嘿,这有点像闭包."我知道这个假设在某种程度上从根本上是错误的,在网上搜索后,我没有找到对这种比较的任何分析.

I am just now learning about function pointers and, as I was reading the K&R chapter on the subject, the first thing that hit me was, "Hey, this is kinda like a closure." I knew this assumption is fundamentally wrong somehow and after a search online I didn't find really any analysis of this comparison.

那么为什么 C 风格的函数指针与闭包或 lambda 有根本的不同呢?据我所知,这与函数指针仍指向已定义(命名)函数的事实有关,而不是匿名定义函数的做法.

So why are C-style function pointers fundamentally different from closures or lambdas? As far as I can tell it has to do with the fact that the function pointer still points to a defined (named) function as opposed to the practice of anonymously defining the function.

为什么在第二种情况下将函数传递给一个被视为更强大的函数,在这种情况下,它是未命名的,而不是在第一种情况下它只是一个普通的日常函数被传递?

Why is passing a function to a function seen as more powerful in the second case, where it is unnamed, than the first where it is just a normal, everyday function that is being passed?

请告诉我将两者进行如此密切比较的方式和原因是错误的.

Please tell me how and why I am wrong to compare the two so closely.

谢谢.

推荐答案

A lambda(或 closure) 封装了函数指针和变量.这就是为什么,在 C# 中,你可以这样做:

A lambda (or closure) encapsulates both the function pointer and variables. This is why, in C#, you can do:

int lessThan = 100;
Func<int, bool> lessThanTest = delegate(int i) {
   return i < lessThan;
};

我在那里使用了一个匿名委托作为闭包(它的语法比等效的 lambda 更清晰,更接近 C),它将lessThan(堆栈变量)捕获到闭包中.在评估闭包时,lessThan(其堆栈帧可能已被破坏)将继续被引用.如果我改变lessThan,那么我改变比较:

I used an anonymous delegate there as a closure (it's syntax is a little clearer and closer to C than the lambda equivalent), which captured lessThan (a stack variable) into the closure. When the closure is evaluated, lessThan (whose stack frame may have been destroyed) will continue to be referenced. If I change lessThan, then I change the comparison:

int lessThan = 100;
Func<int, bool> lessThanTest = delegate(int i) {
   return i < lessThan;
};

lessThanTest(99); // returns true
lessThan = 10;
lessThanTest(99); // returns false

在 C 中,这是非法的:

In C, this would be illegal:

BOOL (*lessThanTest)(int);
int lessThan = 100;

lessThanTest = &LessThan;

BOOL LessThan(int i) {
   return i < lessThan; // compile error - lessThan is not in scope
}

虽然我可以定义一个带有 2 个参数的函数指针:

though I could define a function pointer that takes 2 arguments:

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

但是,现在我在评估它时必须传递 2 个参数.如果我希望将此函数指针传递给 lessThan 不在作用域内的另一个函数,我必须通过将其传递给链中的每个函数或将其提升为全局函数来手动保持它处于活动状态.

But, now I have to pass the 2 arguments when I evaluate it. If I wished to pass this function pointer to another function where lessThan was not in scope, I would either have to manually keep it alive by passing it to each function in the chain, or by promoting it to a global.

虽然大多数支持闭包的主流语言都使用匿名函数,但并没有要求.可以有没有匿名函数的闭包,也可以有没有闭包的匿名函数.

Though most mainstream languages that support closures use anonymous functions, there is no requirement for that. You can have closures without anonymous functions, and anonymous functions without closures.

总结:闭包是函数指针+捕获变量的组合.

Summary: a closure is a combination of function pointer + captured variables.

这篇关于函数指针、闭包和 Lambda的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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