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

这篇具有很好参考价值的文章主要介绍了从源码理解Scala中函数reduceRight的计算过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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


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

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

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

从源码理解Scala中函数reduceRight的计算过程,Scala,scala,开发语言,后端,reduceRight源码分析

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

从源码理解Scala中函数reduceRight的计算过程,Scala,scala,开发语言,后端,reduceRight源码分析

举例来说: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是最顶层特质的方法实现,也最容易看懂。所以先把那个最容易的看懂。

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

从源码理解Scala中函数reduceRight的计算过程,Scala,scala,开发语言,后端,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方法的重写。

从源码理解Scala中函数reduceRight的计算过程,Scala,scala,开发语言,后端,reduceRight源码分析

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

从源码理解Scala中函数reduceRight的计算过程,Scala,scala,开发语言,后端,reduceRight源码分析

实际上走的是这段代码:

override /*IterableLike*/
def reduceRight[B >: A](op: (A, B) => B): B =
  if (isEmpty) throw new UnsupportedOperationException("Nil.reduceRight")
  else if (tail.isEmpty) head
  else 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文章来源地址https://www.toymoban.com/news/detail-585352.html

到了这里,关于从源码理解Scala中函数reduceRight的计算过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • scala函数大全

    目录 ++函数,合并两个集合并且返回一个新数组,++:返回类型和:后的集合类型一样 ++:函数,操纵数的类型决定返回结果的类型 +:函数,:于数组前放入元素 /:函数,执行最后一个括号内的加减乘除操作以二叉树的形式 :函数,执行最后一个括号内的加减乘除操作以二叉树的形式 addSt

    2023年04月09日
    浏览(30)
  • Scala方法和函数

    方法和函数的作用几乎是一样的,但是函数在使用的过程中更加灵活和多样化 scala中函数是头等公民 . 可以作为方法的返回值和参数使用 scala是一个集面向对象和面向函数于一身的编程语言 , 灵活的函数是函数式编程的一种体现 函数的使用使代码更加简洁和灵活 scala中一种函

    2024年02月09日
    浏览(30)
  • Scala之函数式编程

    目录 函数和方法的区别:  参数默认值:  函数至简原则---能省则省: 至简原则细节 匿名函数的化简: 匿名函数至简原则: 高阶函数: 高阶函数的三种用法: (1)函数可以作为值进行传递 (2)函数可以作为参数进行传递** 匿名化简: 柯里化写法: 闭包: 递归: 优化

    2023年04月10日
    浏览(40)
  • scala函数式编程

    参考 https://juejin.cn/post/7006243598714798094 https://www.cnblogs.com/listenfwind/p/11209383.html https://docs.scala-lang.org/zh-cn/scala3/book/introduction.html https://bbs.huaweicloud.com/blogs/126988 https://bbs.huaweicloud.com/blogs/126988 https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==mid=2665513393idx=1sn=c1d6caca8ef9972f1105df982f15bb58chksm=80d

    2024年01月20日
    浏览(43)
  • Scala学习(三)---函数式编程

    Scala语言是一个完全面向对象的编程语言。万物皆是对象 对象的本质:对数据和行为的一个封装 在解决问题的时候,将问题分解成一个个的步骤,将每一个步骤进行封装(函数),通过调用这些封装好的步骤来解决问题。 Scala语言是一个完全函数式编程的语言。万物皆是函数。

    2024年02月04日
    浏览(35)
  • 大数据开发语言Scala(一)——scala入门

    累了,基础配置不想写了,直接抄了→Scala的环境搭建 这里需要注意的是,创建新项目时,不要用默认的Class类,用Object,原因看→scala中的object为什么可以直接运行 package : 包,等同于java中的package object :,声明一个单例对象(伴生对象) main方法 :从外部可以直接

    2024年02月05日
    浏览(56)
  • Scala 05 —— 函数式编程底层逻辑

    该文章来自2023/1/14的清华大学交叉信息学院助理教授——袁洋演讲。 函数式编程 什么是函数式编程? y=f(x) 无副作用: y只是依赖x,不会依赖其他变量 确定性关系:重新跑100次代码,得到的结果是一样的 不会给世界带来副作用。算完f(x)然后就得到了y,其他什么都没变。 什

    2024年04月29日
    浏览(38)
  • spark源码的scala解析

    一、scala抽象类和java的有何不同? 在org/apache/spark/util/collection/SortDataFormat.scala中有以下抽象类 private[spark] abstract class SortDataFormat[K, Buffer] {...}    然后在org/apache/spark/graphx/Edge.scala中,直接调用了xxx = new SortDataFormat[Edge[ED], Array[Edge[ED]]] {...} 为啥可以直接new一个抽象类呢??sc

    2024年02月12日
    浏览(36)
  • Scala函数式编程【从基础到高级】

    目录 函数基础 基本语法 函数参数 函数至简原则 至简原则细节  函数高级 高阶函数 函数的3种高阶用法: 1、函数作为值传递 2、函数作为参数传递 匿名函数作参数传递 3、函数作为返回值传递 匿名函数的至简规则 高阶函数的应用  案例-将数组中的元素全部+1后返回  匿名

    2024年02月11日
    浏览(43)
  • scala 短文本相似度计算

    simHash类的算法更适合长文本的相似度判断,而短文本可考虑一下几种方法: 一、编辑距离+jacard距离 对于dataframe,getLevenshtein可利用原生的levenshtein函数 二、md5 三、语义向量模型 其他思路 python的difflib使用

    2024年02月15日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包