专栏首页RunhwGuo的Coding之路kotlin源码阅读——函数式编程
原创

kotlin源码阅读——函数式编程

Filename:_Collections.kt/Iterator.kt

我主要写Kotlin源码阅读,函数式编程的基本概念,概念大家可以在网上做一些了解,这里推荐一下百度百科的定义,函数式编程概念,蛮清晰的。

无论何种语言,一般都会提供map/reduce/filter等三大类函数式模型,比如JavaScript/Python/Dart等都是有的,C++也有但是支持地并不是那么友好,废话不多说,开始。

1.map

概念:映射函数,将一个集合经过传入的变换(transform)函数,映射成另外一个集合。

下面,我们来写一些demo,计算一个字符串数组每个字符串的长度。

简单的代码如上,map函数是直接作用在myStringList上的。我们看一下map的具体实现。

由于函数式编程,是没有副作用的,输入一样,输入也一定一样,所以map的返回值是new出来的对象。

这里新对象构建ok,就看一下map到底是怎么遍历的,一揭函数式编程FP的神秘面纱。

我们知道,最终还是调用的命令式,for语句,我们看到了源码,知道最终是怎么实现的了,所以觉得函数式编程没有什么神秘了吧。

这里想提一个问题,在上一张图,给新数组默认初始值是10,如果这个case走到了,那么容器初始值是10,如果新数组的长度超过了10,怎么办呢?Kotlin的ArrayList是复用Java的ArrayList,这里就涉及到了Java JVM ArrayList的扩容逻辑啦,感兴趣的小伙伴,可以自行浏览一下ArrayList的源码实现。

再上一张源码截图,我们发现map的兄弟还是挺多的,我们再来分析一个mapIndexedNotNull函数吧,以增加熟悉程度。

先看一下mapIndexedNotNull的函数定义:

如图,我们知道这个函数,相比于map有两个特点:

a)遍历的时候,带下标index。

b)只包含transform不为空的item。

废话不多说,直接上代码:

如图,我们看到,a)是通过index = 0,然后++实现的,而item使用this中取出来的,那b)是如何实现的,请看第一个截图的?.问号表达式,意思是如果为null就不执行let的函数体。

运行结果:

2.reduce

第一大类的map,我们很容易理解,就是遍历+映射。那么这里的reduce怎么理解呢?我觉得这里应该是遍历+累积,废话少说,代码最清楚。

Demo如上图。

看一下reduce的源码,从注释看,我们知道这个函数是从第一个元素开始,从左到右地累积执行传入的operation函数,比如求和,阶乘等都是这种概念。这里源码非常清晰明了,就是获取第一个元素,如果没有,就抛出异常,然后取第一个元素作为积累的初始值,然后循环执行operation,赋值给“初始值”,直至循环完毕。

同样,reduce的其他“兄弟函数”,也是差不多的,这里就不做过多重复分析了。

3.filter

二话不说,先上代码。

这是简单的一个filter demo,过滤出字符串长度是偶数的字符串。

看一下内部实现filterTo,又是new一个ArrayList(无副作用)

下面的截图,还用说太多嘛,就是往新的ArrayList中添加符合predicate lambda条件的元素。

所以,filter就是一个语法糖的封装,并不神秘。

同样filter也有一大家子的兄弟。

大致都是一样,只不过又封装了非空或者是not而已。

总结一下:

函数式编程,在我看来是一个新思路,新的编程模型,简单,简洁,但是内部实现也都是通过命令式来实现的,鼓励大家多用,多写优雅可读的代码。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Kotlin源码阅读——Math

    NaN其实在JVM上的语言,并不像JS一样,要特别地学习一下,但是NaN这个逻辑也确实存在。代码跟进去:

    Runhwguo
  • Kotlin源码阅读——IO

    filename:Console.kt/FileTreeWalk.kt/ReadWrite.kt/FileReadWrite.kt

    Runhwguo
  • Kotlin源码阅读——Standard模块

    Filename:stdlib/src/kotlin/util/Standard.kt

    Runhwguo
  • 将现有项目上传至github

    1、在github上新建远程仓库(空库),注意不要填写readme,不然github会初始化一个仓库,会和本地仓库产生版本冲突。

    week
  • 【腾讯云Serverless】使用云函数快速打造一个智障微信公众号自动回复机器人

    于上周五发现了一个有趣的仓库: co-wechat。突发奇想,我不要你觉得,我要我觉得,腾讯云云函数配合该库,理论上可以快速搭建一个微信公众号的自动回复机器人。...

    Juli
  • FindBugs使用

    FindBugs简介:  FindBugs是一个开源的eclipse 代码检查工具,是一种白盒静态自动化测试工具;  它可以简单高效全面地帮助我们发现程序代码中...

    用户1155943
  • [前端]一个空格引发的血案

    是用flex布局,中间是grow等于1,内容是铺满整个container的 但是却出现了这种情况

    Tuzei
  • 学习July博文总结——支持向量机(SVM)的深入理解(上)

    前言 本文是参照CSDN的July大神的热门博文《支持向量机通俗导论(理解SVM的三层境界》)写的。目的是因为July大神文中说,SVM理论的理解,需要一遍一遍...

    剑影啸清寒
  • 对象存储文件打开方式的解决方案

    对象存储(cos),之前老版本默认打开方式为下载;后续貌似改版之后默认打开方式为预览即浏览器直接显示文件。

    Mr.Du
  • Angular实战项目(2)

    ng new taskmgr -si --style=scss installing ng

    达达前端

扫码关注云+社区

领取腾讯云代金券