加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么scala @tailrec不能在Option.flatMap上使用?

发布时间:2020-12-16 18:07:06 所属栏目:安全 来源:网络整理
导读:在 scala中,以下两个函数用于完全相同的目的: @tailrecfinal def fn(str: String): Option[String] = { Option(str).filter(_.nonEmpty).flatMap { v = fn(v.drop(1)) }}@tailrecfinal def fn2(str: String): Option[String] = { Option(str).filter(_.nonE
在 scala中,以下两个函数用于完全相同的目的:

@tailrec
final def fn(str: String): Option[String] = {
  Option(str).filter(_.nonEmpty).flatMap { v =>
    fn(v.drop(1))
  }
}

@tailrec
final def fn2(str: String): Option[String] = {
  Option(str).filter(_.nonEmpty) match {
    case None    => None
    case Some(v) => fn2(v.drop(1))
  }
}

但是@tailrec仅适用于第二种情况,在第一种情况下它将生成以下错误:

Error: could not optimize @tailrec annotated method fn: it contains a
recursive call not in tail position
Option(str).filter(_.nonEmpty).flatMap { v =>

为什么会出现这个错误?为什么这两个代码生成不同种类的JVM字节码

解决方法

要使fn成为尾递归,递归调用必须是函数中的最后一个操作.如果将fn传递给另一个函数(如flatMap),那么另一个函数可以在调用fn后自由执行其他操作,因此编译器无法确定它是尾递归的.

在某些情况下,编译器可以检测到调用fn是另一个函数中的最后一个操作,但在一般情况下不是.并且这将依赖于该其他函数的特定实现,因此如果其他函数被更改,则tailrec注释可能变得无效,这是不期望的依赖性.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读