浅析匿名函数、lambda表达式、闭包(closure)区别与作用
浅析匿名函数、lambda表达式、闭包(closure)区别与作用
所有的主流编程语言都对函数式编程有支持,比如c++11、python和java中有lambda表达式、lua和JavaScript中有闭包(closure)、ObjectC中有块(blocks,^)。那么这几个概念有什么共性和区别呢,只用普通函数不行吗,为什么要创造这些炫酷的概念呢?
一.匿名函数、lambda、closure区别
从功能性上说lambda和closure(或是OC中的blocks)是一个东西,只是不同语言的不同称呼罢了,它们都是匿名函数。若匿名函数捕获了一个外部变量,那么它就是一个closure。
二.匿名函数、lambda、closure作用
简单说,引入它们的作用有2个:
- 简洁
- 捕获变量
首先说简洁,匿名函数可以在其他函数内部声明与定义,不用另外写个命名函数,举个栗子,显示c++vector中每个值,若不使用匿名函数,代码是这样的
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; void show(int & value) {
std::cout << "value " << value << std::endl;
} int main() {
vector<int> * v = new vector<int>(, ); for_each(v->begin(), v->end(), show); return ;
}
若使用匿名函数是这样的:
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std; int main() {
vector<int> * v = new vector<int>(, ); for_each(v->begin(), v->end(), [](int & v){
11 std::cout << "value " << v << std::endl;
12 }); return ;
}
什么是捕获变量呢?就是让匿名函数可以使用匿名函数外定义的变量,但是匿名函数内的函数外变量是外部变量的一个clone(C++11可以捕获引用,不是clone。OC中有__block,也可以直接改变外部变量的值),在匿名函数内修改(诺能)外部变量不会影响到外部变量。可以说closure就是函数+捕获的变量。以lua为例:
local intValue = ; local func = function (p)
intValue = intValue + p;
return intValue;
end print(func());
print(func());
print(intValue)
打印的结果为:13,16,10。可见匿名函数的外部变量被捕获到了func中。
三.匿名函数、lambda、closure在各个语言中的使用方式:
1.ObjectC:
在ObjectC中,匿名函数被称为blocks(块),即可以改变捕获的原值、又可以捕获克隆、但不能改变克隆值的值。捕获并改变外部值,需要用__block,否则复制语句会报错,使用代码如下:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
__block int foo = ;
int (^blockFunc)(int p) = ^(int p) {
foo += p;
return foo;
};
NSLog(@"%d", blockFunc());
NSLog(@"%d", foo);
}
return ;
}
2.C++:
C++中匿名函数被称为lambda,即可以改变捕获的原值、又可以捕获克隆、又可以改变克隆值的值,语法形式可以简单归纳如下:
[capture](params)ops->ret{body;}
capture是捕获列表,params是参数表,opt是可选选项,ret是返回值类型,body是函数体。具体怎么使用可以参考C++11 lambda 表达式解析和C++11 lambda 表达式。
3.lua:
lua中的匿名函数被称为闭包(closure),只能捕获和改变原值的克隆,不能改变原值(table除外)
4.python:
python中的匿名函数被称为lambda,只能捕获克隆值,且不能改变他。
浅析匿名函数、lambda表达式、闭包(closure)区别与作用的更多相关文章
- 【Unity|C#】基础篇(9)——匿名函数 / Lambda表达式
[学习资料] <C#图解教程>(第13章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...
- 匿名函数 lambda表达式(lambda expression)
阅读g2log时,发现有两行代码居然看不懂. 1. auto bg_call = [this, log_directory]() {return pimpl_->backgroundChang ...
- (28)C#委托,匿名函数,lambda表达式,事件
一.委托 委托是一种用于封装命名和匿名方法的引用类型. 把方法当参数,传给另一个方法(这么说好理解,但实际上方法不能当参数,传入的是委托类型),委托是一种引用类型,委托里包含很多方法的引用 创建的方法 ...
- Qt中使用匿名函数lambda表达式
一.为什么要使用匿名函数lamdba 首先,lambda表达式可以使代码变得简单,C++中,一个lambda表达式表示一个可调用的代码单元.如代码: #include <QCoreApplica ...
- Python匿名函数——lambda表达式
如果要定义的函数很简单,一个return语句就能搞定,可以使用lambda表达式来定义, lambda表达式的语法如下: lambda parameters: expression lambda表达式 ...
- python做中学(八)匿名函数lambda的用法
匿名函数,顾名思义即没有名称的函数,和def定义的函数的最大区别在于匿名函数创建后返回函数本身(即匿名函数不需要return来返回值),表达式本身结果就是返回值,而def创建后则赋值给一个变量名,在P ...
- 匿名函数 =匿名方法+ lambda 表达式
匿名函数的定义和用途 匿名函数是一个"内联"语句或表达式,可在需要委托类型的任何地方使用. 可以使用匿名函数来初始化命名委托[无需取名字的委托],或传递命名委托(而不是命名委托类型 ...
- 『Python基础-14』匿名函数 `lambda`
匿名函数和关键字lambda 匿名函数就是没有名称的函数,也就是不再使用def语句定义的函数 在Python中,如果要声匿名函数,则需要使用lambda关键字 使用lambda声明的匿名函数能接收任何 ...
- 匿名函数(lambda)在列表生成式和生成器中的应用示例
匿名函数(lambda)在列表生成式和生成器中的应用示例 列表生成式中实例 先看题: 以下代码的输出是什么?请给出答案并解释: def func(): return [lambda x: x * i ...
随机推荐
- [计算机网络]简易http server程序
好久没输出了,知识还是要写下总结才能让思路更加清晰.最近在学习计算机网络相关的知识,来聊聊如何编写一个建议的HTTP服务器. 这个http server的实现源代码我放在了我的github上,有兴趣的 ...
- Entity Framework 6 Recipes 2nd Edition(10-10)译 - > 为TPH继承的插入、更新、删除操作映射到存储过程
10-10. 为TPH继承的插入.更新.删除操作映射到存储过程 问题 TPH继承模型,想把它的插入.修改.删除操作映射到存储过程 Solution 假设数据库有一个描述不同种类的产品表(Product ...
- golang的安装
整理了一下,网上关于golang的安装有三种方式(注明一下,我的环境为CentOS-6.x, 64bit) 方式一:yum安装(最简单) rpm -Uvh http://dl.fedoraprojec ...
- MySQL语句学习记录
注意,命令行下,每条语句最后都需要加分号. 1.显示所有数据库 SHOW DATABASES 2.使用某数据库 如mysql数据库 use mysql (sql语句不区分大小写) 3.显示所有表 ...
- SI与EMI(一) - 反射是怎样影响EMI
Mark为期两天的EMC培训中大概分成四个时间差不多的部分,简单来说分别是SI.PI.回流.屏蔽.而在信号完整性的书籍中,也会把信号完整性分为:1.信号自身传输的问题(反射,损耗):2.信号与信号之间 ...
- PHP Excel 下载数据,并分页下载
直接上代码: 调用下载Excel: $total=$duoduo->count(MOD.' as a',$where); $objExcel= SelfExcelObject(); //导出 i ...
- 深入理解CSS3 Animation 帧动画
CSS3我在5年之前就有用了,包括公司项目都一直在很前沿的技术. 最近在写慕课网的七夕主题,用了大量的CSS3动画,但是真的沉淀下来仔细的去深入CSS3动画的各个属性发现还是很深的,这里就写下关于帧动 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(45)-工作流设计-设计步骤
系列目录 步骤设计很重要,特别是规则的选择. 我这里分为几个规则 1.按自行选择(在起草时候自行选审批人,比较灵活) 2.按上级(无需指定,当时需要知道用户的上司是谁,可以在职位管理设置,或者在用户表 ...
- Linux驱动开发—— IS_ENABLED
在閱讀Linux內核代碼的時候,會經常遇到下面的幾個宏函數: IS_ENABLED 這個宏最爲常見 IS_BUILTIN IS_MODULE IS_REACHABLE 這幾個宏函數是在文件inclu ...
- 卷积神经网络提取特征并用于SVM
模式识别课程的一次作业.其目标是对UCI的手写数字数据集进行识别,样本数量大约是1600个.图片大小为16x16.要求必须使用SVM作为二分类的分类器. 本文重点是如何使用卷积神经网络(CNN)来提取 ...