C++雾中风景8:Lambda表达式

上一篇C++的博客是Long Long ago了,前文讲到在看Lambda表达式的内容。笔者首次接触Lambda表达式应该是学习Python语言的时候,当时也不太明白这种表达方式的精髓,后续接触了Scala与Java8的链式调用与Lambda结合的方式,深陷无法自拔。所以借上一篇闭包的内容。我们来完整的梳理一下C++之中的Lambda表达式。

1.什么是Lambda表达式?

Lambda表达式是函数式编程的重要的语法结构。
Lambda 表达式(lambda expression)说起来很简单,就是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包。(注意和数学传统意义上的不同)。(本质上Lambda表达式就是将函数作为是一个匿名对象进行操作

其实缺少Lambda表达式的编程语言并不会影响编程语言的逻辑表达,Lambda表达式核心就是提供一个好用的语法糖:可以直接定义一个函数,而不需要将定义函数和语法内容分开,这样有助于将逻辑用更紧凑的方式表达出来。假如需要定义一个函数,恰巧这个函数仅仅使用一次,然后又需要给它定义一个名字,作为懒惰的程序员就需要搬出Lambda表达式了。咱们看一段Python代码,过滤一个list之中的偶数,这是一个很简单的需求,我们先看看不使用Lambda表达式的方式:

def isOdd(n):
    return n & 1;

nums = [1,2,3,4,5,6]
nums = filter(isOdd,nums)

显然这里需要额外定义一个代码逻辑十分麻烦:首先需要跳脱出运行代码而去查看定义的isOdd函数的代码,其次,这里需要实现的过滤逻辑很简单。这种场合是最适合使用Lambda表达式的场景,我们来看看Lambda表达式是怎么优化上述代码的:

nums = [1,2,3,4,5,6]
nums = filter(lambda x:x & 1,nums)

好吧,很优雅的用Lambda表达式解决了同样的需求,表述也十分清晰:
下面的几个使用场景是适用于Lambda表达式的:

  • (1)代码定义的逻辑与执行逻辑对接的更加紧凑。
  • (2)代码更加简洁。
  • (3)能够支持闭包。

2.C++之中的Lambda表达式

C++在C++11之中添加了Lambda表达式的语法结构,Lambda语法结构如下所示:

[capture](parameters)->return-type {body}

接下来,我们来一一分析各个部分所代表的含义,以及具体的使用方式:

  • [capture]
    capture代表捕获外部的变量,这个使用的方式笔者在上一篇有关闭包的内容之中就有过示例,变量捕获是Lambda表达式之中,最为复杂的一环,我们来看一看其中各种表示方式的含义:
    • [] 不捕获任何变量(但是必须得写,编译器通过捕获结构识别Lambda表达式
    • [&} 通过引用的方式捕获外部作用域中所有变量
    • [=] 通过拷贝的方式捕获外部作用域中所有变量
      上述两种方式都过于粗暴了,实际的话,尽量采用下面的模式来限定所引用的变量,不要随意引用
    • [x, &y] x按值传递,y按引用传递
    • [this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。

可以看到,[capture]的语法结构捕获了外部变量,通过这样的方式实现了闭包

  • (parameters)
    这个部分很简单,类似于通常函数使用的参数列表,使用方式也没有区别。

  • ->return-type
    显式指明由Lambda表达式所返回的返回值类型。这里通常建议不写,因为C++编译器会通过类型推断的方式来推断出函数的返回值类型,而且前面的->也可以省略。

  • {body}
    花括号括起来的函数体,则没什么好说的了,就是实现函数逻辑的部分了。

同样的,我们来看看上文用python实现的过滤偶数的代码在C++之中是如何实现的:

    vector<int> nums = {1,2,3,4,5,6,7};
    vector<int> newNums(nums.size());
    
    auto last = copy_if(nums.cbegin(), nums.cend(),newNums.begin(),[](int x){return !(x & 1);});
    for_each(newNums.begin(), last, [](int x) {
        cout << x << endl;
    });

和python的实现相比,由于缺少了链式调用的方式,所以看起来C++实现的版本并没有简化多少应用逻辑,反而看起来略显杂乱。但是这并不妨碍我们在适当的地方运用Lambda表达式,来优化我们的代码结构。

3.其他语言与Lambda表达式

  • Java
    Java在Java 8的版本终于千呼万唤始出来的Lambda表达式确实是让个人很喜欢,个人也觉得Java 8对于Java这门语言有极其深远的影响。我们来看看Java之中是如何实现上文的逻辑的:
public static void main(String[] args) {
        int[] nums = {1,2,3,4,5,6,7};
        IntStream.of(nums).filter((x)->{return (x & 1) == 1;}).forEach(System.out::println);
    }

相比C++而言优雅了很多,而且参数类型也能做到类型推断,对程序员来说确实更加友好了。

坦白说:Java是一门很幸运的语言,更上了移动开发,大数据的浪潮。不过随着Google与Oracle的官司,不知道Java未来是否还能继续现在的强势地位。

  • Golang
    没有Lambda表达式,咱们要的是简洁明晰,不要学Geek那一套玩意。

4.小结

感觉本文干货有点略少,吐槽略多,见谅哈~~~。关于C++之中的Lambda表达式就和大家聊到这里,希望大家在实际Coding之中可以用好它,来尽量简洁化自己的代码结构。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,050评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,538评论 1 306
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,673评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,622评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,047评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,974评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,129评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,893评论 0 209
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,654评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,828评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,297评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,619评论 3 262
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,326评论 3 243
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,176评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,975评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,118评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,909评论 2 278

推荐阅读更多精彩内容