从源码理解Scala中函数reduceRight的计算过程

news/2024/11/17 23:56:49/

水善利万物而不争,处众人之所恶,故几于道💦

  以List集合为例,进行reduceRight()的计算过程分析,总体分为两部分,一部分是看最顶层特质的那个通用的reduceRight方法,另一部分是讲直接混入的特质的那个重写的reduceRight方法,两种方式最终结果一致。


例如:
val list2: List[Int] = List(3, 4, 5, 8, 10)
println(list2.reduceRight(_ - _))   // 6

  上面的这两行代码输出的结果是6
  接下来我们从源码的角度刨析一下这个结果是怎么算出来的

  1. 首先我们点进list的reduce里面,查看他的源代码

在这里插入图片描述

  1. 点进去后在这个特质里面找到reduceRight方法
      这个方法它首先是判断了一下方法调用这也就是哪个集合是否为空,如果为空,直接抛异常。
      其次他就开始进行reduceRight的操作。看代码,他的操作是:将集合反转,然后调用reduceLeft方法,这个op就是我们的_-_操作,也就是简化/规约的逻辑。它具体执行的时候将传入的两个参数进行了位置调换。

在这里插入图片描述

举例来说:List(3, 4, 5, 8, 10).reduceRight(_ - _)

  1. 它先把集合反转得到List(10, 8, 5, 4, 3).reduceLeft(_ - _)

  2. 然后在进行相减操作的时候,传入的参数本来是(x,y)也就是x=10,y=8 但是它方法体中调用的时候是op(y, x)也就是op(8, 10)

  3. 带入到我们的例子中就是:8-10,然后 5-(8-10) ,4-(5-(8-10)) , 3-(4-(5-(8-10)))。算出最总结果是6



刚才那个reduceRight是最顶层特质的方法实现,也最容易看懂。所以先把那个最容易的看懂。

下面这个是真正执行的时候走的方法。

在这里插入图片描述

这两个特质是父子关系,LinearSeqOptimized特质是TraversableOnce特质的子特质,

TraversableOnce特质里面的reduceRight方法实现就是:

def reduceRight[B >: A](op: (A, B) => B): B = {if (isEmpty)throw new UnsupportedOperationException("empty.reduceRight")reversed.reduceLeft[B]((x, y) => op(y, x))
}

实际上走的LinearSeqOptimized特质里面的reduceRight方法其实是对父特质里面reduceRight方法的重写。

在这里插入图片描述

查看TraversableOnce特质的层次结构,看到LinearSeqOptimized特质是它的子特质。

在这里插入图片描述

实际上走的是这段代码:

override /*IterableLike*/
def reduceRight[B >: A](op: (A, B) => B): B =if (isEmpty) throw new UnsupportedOperationException("Nil.reduceRight")else if (tail.isEmpty) headelse op(head, tail.reduceRight(op))

 1. 首先它判断了一下集合是否为空,空的话直接抛异常

 2. 否则判断集合的尾是否为空,如果为空的话直接将头部返回。意思就是,如果集合中只有一个元素的话,直接将该元素返回。

 3. 接下来进行我们的简化/规约操作,op是我们传过来的函数,也就是(a:Int,b:Int)=>{a-b}。op的第一个参数是集合的头,也就是3,第二个参数是尾再进行reduceRight(op)操作,可以看到有递归调用,所以第一次执行后的结果是:

3 - List(4,5,8,10).reduceRight(_-_)  // 第一次执行然后递归调用,第二次执行...3 - (4 - List(5,8,10).reduceRight(_-_)) // 第二次递归调用3 - (4 - (5 - List(8,10).reduceRight(_-_)))  //第三次递归调用3 - (4 - (5 - (8 - List(10).reduceRight(_-_))))  //第四次递归调用第五次递归调用的时候,由于集合中只有一个元素,
在进行 else if 条件判断的时候,返回 10 ,也就是到了递归出口3 - (4 - (5 - (8 - 10)))  //第五次递归调用

最终算出结果是 6


http://www.ppmy.cn/news/932886.html

相关文章

html中字体 楷体_(收藏)css怎么设置字体为楷体?

——本篇文章小编将和大家讲讲如何在CSS里设置字体为楷体,还有五类通用字体说明以及其他的字体样式表示,感兴趣的朋友可以看看,希望对你有所帮助。 ——各位小伙伴在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一…

发字的楷书写法图片_“快”字楷体书法 图片 写法

展开全部 楷体书法学习方法: 一、楷书临习章法 章法是书法艺术形式美的重要组成部分。点画是线条美,间架结构32313133353236313431303231363533e4b893e5b19e31333431356631是局部的构图美,章法是整体构图美。 1、整齐一律。楷书章法的整体感&…

楷书书法规则_楷书笔画书写八大规律

(一)楷书的基本点有五个: 斜点——反捺的浓缩 竖点——垂露竖的浓缩左点——右短竖的浓缩 撇点——短斜撇的浓缩 提点——提的浓缩 这些点是这五个对应笔画的缩写——去中间行笔,接两头起笔和收笔。 (二)组合点的用…

楷书书法规则_硬笔书法中楷书结构八条原则

1、横平竖直2、重心平稳 3、笔画呼应 4、疏密有序 5、比例和谐 6、向背分明 、7、让就合理 8、伸展得当 [关键词] 平稳、呼应、横平、有序、和谐、分明、合理、 [正文] 各种笔画的结合造就了汉字,要使每个人的字写得正确、美观、规范,就必须掌握一定的法则组织笔画,这一法则…

端午节书法作品楷书内容_端午节楷书怎么写

1. 端午节快乐用楷书怎么写 端午节快乐 2. "中秋快乐"这几个字的正楷书法怎么写 "中秋快乐"这几个字的正楷书法: 下面来了解下中秋节: 1.中秋节,又称月夕、秋节、仲秋节、八月节、八月会、追月节、玩月节、拜月节、女儿节…

html中字体 楷体_css怎么设置字体为楷体?

本篇文章小编将和大家讲讲如何在CSS里设置字体为楷体,还有五类通用字体说明以及其他的字体样式表示,感兴趣的朋友可以看看,希望对你有所帮助。 CSS使用font-family属性来定义字体类型。css设置字体为楷体的语句为:font-family: &q…

Linux 6.5 内核提供对 USB4 v2 的初步支持

导读最新内核补丁显示,英特尔正在为 Linux 6.5 内核提供对 USB4 v2 的初步支持,并在其新的英特尔 Barlow Ridge 离散控制器上进行初步启用。 去年,USB4 v2.0 规范作为 USB4 标准的下一代版本发布。 USB4 v2 可通过 USB Type-C 线支持 80 Gbp…

Python教程(4)——Python开发工具PyCharm的下载与安装

PyCharm是一种专业的Python集成开发环境(IDE),由JetBrains公司开发和维护。它提供了丰富的功能和工具,帮助开发人员更高效地编写、调试和测试Python代码。如果是一些大型Python项目强烈推荐用这个来开发。今天我们来介绍一下PyCha…