我正在通过 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/