Scala 使用可变变量来实现其 api

标签 scala api recursion tail-recursion

我正在通过 Coursera 类(class) (progfun) 学习 Scala。

我们正在学习从功能上思考,并在可能的情况下使用尾递归来实现功能/方法。

作为列表函数上 foreach 的示例,我们已经教过如何实现它:

def foreach[T](list: List[T], f: [T] => Unit) {
    if (!list.isEmpty) foreach(list.tail) else f(list.head)
}

然后当我在一些 Scala apis 中发现以下实现时,我感到很惊讶:
override /*IterableLike*/
  def foreach[B](f: A => B) {
    var these = this
    while (!these.isEmpty) {
      f(these.head)
      these = these.tail
    }
}

那么为什么我们学会了使用递归并避免使用可变变量,而 api 是由相反的技术实现的呢?

看看scala.collection.LinearSeqOptimized哪里scala.collection.immutable.List延长。 (在 List 类本身中找到了类似的实现)

最佳答案

不要忘记 Scala 旨在成为一种多范式语言。出于教育目的,最好了解如何读写尾调用递归函数。但是在日常使用该语言时,重要的是要记住它不是纯 FP。

库的一部分可能早于 TCO 和 @tailrec注解。您必须查看提交历史才能找到答案。
foreach 的实现可能使用可变变量,但从外面看,它似乎是纯的。最终,这正是 TCO 在幕后所做的。

关于Scala 使用可变变量来实现其 api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31368652/

相关文章:

java - 如何翻转这把尺子?

php - Symfony API Controller 必须返回响应

api - rest api交易不会从账户中扣除

api - 非 GPS 设备上的 J2ME 位置 API (JSR 179)

java - ApacheSpark从http来源(例如csv等)读取数据帧

javascript - JS 停止控制流直到异步 setTimeout 返回

c++ - 递归数据结构的前向声明

mongodb - 如何以 ISO 格式而不是 Long [Play、Scala 和 ReactiveMongo] 格式在 MongoDB 中存储日期?

scala - 如何在 Scala 中输入强制转换 Char/Int?

scala - 使用 scalajs 创建自定义 DOM 事件