浅析匿名函数、lambda表达式、闭包(closure)区别与作用
来源:互联网 发布:网络电视tv版哪个好 编辑:程序博客网 时间:2024/06/05 14:35
浅析匿名函数、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中每个值,若不使用匿名函数,代码是这样的
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 using namespace std; 5 6 void show(int & value) { 7 std::cout << "value " << value << std::endl; 8 } 9 10 int main() {11 vector<int> * v = new vector<int>(3, 1);12 13 for_each(v->begin(), v->end(), show);14 15 return 0;16 }
若使用匿名函数是这样的:
1 #include <iostream> 2 #include <vector> 3 #include <functional> 4 #include <algorithm> 5 using namespace std; 6 7 int main() { 8 vector<int> * v = new vector<int>(3, 1); 9 10 for_each(v->begin(), v->end(), [](int & v){11 std::cout << "value " << v << std::endl;12 });13 14 return 0;15 }
什么是 捕获变量 呢?就是让匿名函数可以使用匿名函数外定义的变量,但是匿名函数内的函数外变量是外部变量的一个clone(C++11可以捕获引用,不是clone。OC中有__block,也可以直接改变外部变量的值),在匿名函数内修改(诺能)外部变量不会影响到外部变量。可以说closure就是函数+捕获的变量。以lua为例:
1 local intValue = 10; 2 3 local func = function (p) 4 intValue = intValue + p; 5 return intValue; 6 end 7 8 print(func(3)); 9 print(func(3));10 print(intValue)
打印的结果为:13,16,10。可见匿名函数的外部变量被捕获到了func中。
三.匿名函数、lambda、closure在各个语言中的使用方式:
1.ObjectC:
在ObjectC中,匿名函数被称为blocks(块), 即可以改变捕获的原值、又可以捕获克隆、但不能改变克隆值的值 。捕获并改变外部值,需要用__block,否则复制语句会报错,使用代码如下:
1 #import <Foundation/Foundation.h> 2 3 int main(int argc, const char * argv[]) { 4 @autoreleasepool { 5 __block int foo = 10; 6 7 int (^blockFunc)(int p) = ^(int p) { 8 foo += p; 9 return foo;10 };11 12 NSLog(@"%d", blockFunc(4));13 14 NSLog(@"%d", foo);15 }16 return 0;17 }
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)区别与作用
- 浅析匿名函数、lambda表达式、闭包(closure)区别与作用
- 匿名函数与闭包(closure)
- 匿名函数与闭包(Anonymous Function and Closure)
- closure (闭包 -- 匿名函数) 示例
- Java SE8 Lambda 基础入门---lambda表达式与闭包(closure)
- Lambda表达式和闭包Closure
- javascript 闭包(closure) 与匿名函数的this
- jdk8新特性:Lambda表达式(也称为闭包、可传递的匿名函数)与函数式接口@FunctionalInterface
- closure(闭包)、仿函数、std::function、bind、lambda
- php的闭包(Closure)也就是匿名函数。
- php的闭包(Closure)匿名函数用法详解
- JavaScript 匿名函数(anonymous function)与闭包(closure)
- JavaScript 匿名函数(anonymous function)与闭包(closure)
- 闭包(Closure)和匿名函数
- [从jQuery看JavaScript]-匿名函数与闭包(Anonymous Function and Closure)
- 从jQuery看JavaScript]-匿名函数与闭包(Anonymous Function and Closure)
- [从jQuery看JavaScript]-匿名函数与闭包(Anonymous Function and Closure)
- Pivot 和 Unpivot
- PHP7扩展开发之hello word
- POJ2406 Power Strings
- css背景图片在chrome下正常,IE下不显示
- gym100818I - Olympic Parade
- 浅析匿名函数、lambda表达式、闭包(closure)区别与作用
- 算法学习
- 数组指针和指针数组 原理 及 异同
- PHP时间格式大全
- 字符串的截取
- android新手进阶之录音功能实现
- better support right-to- left layouts的警报
- 在应用程序菜单里添加软件
- Eclipse常用快捷键