gpt4 book ai didi

scala - 在Scala中避免while循环有什么好处吗?

转载 作者:行者123 更新时间:2023-12-03 13:27:57 25 4
gpt4 key购买 nike

阅读专家编写的 Scala 文档可以得到尾递归比 while 循环更好的印象,即使后者更简洁明了。这是一个例子

object Helpers {
implicit class IntWithTimes(val pip:Int) {
// Recursive
def times(f: => Unit):Unit = {
@tailrec
def loop(counter:Int):Unit = {
if (counter >0) { f; loop(counter-1) }
}
loop(pip)
}

// Explicit loop
def :@(f: => Unit) = {
var lc = pip
while (lc > 0) { f; lc -= 1 }
}
}
}

(需要明确的是,专家根本没有解决循环问题,但在示例中,他们选择以这种方式编写循环,就好像本能一样,这就是我提出的问题:我是否应该发展出类似的本能...... )

while 循环唯一可能更好的方面是迭代变量应该是循环体的局部变量,并且变量的变异应该在一个固定的位置,但 Scala 选择不提供这种语法。

清晰度是主观的,但问题是(尾)递归风格是否提供了改进的性能?

最佳答案

我很确定,由于 JVM 的限制,并非每个潜在的尾递归函数都会被 Scala 编译器优化掉,所以对您在 上的问题的简短(有时是错误的)回答性能 没有。

对您的更一般的问题(具有优势)的长答案有点做作。请注意,通过使用 while ,你其实是:

  • 创建一个包含计数器的新变量。
  • 改变那个变量。

  • 一个接一个的错误和可变性的危险将确保,从长远来看,您将引入带有 while 的错误。图案。事实上,您的 times功能可以很容易地实现为:
    def times(f: => Unit) = (1 to pip) foreach f

    这不仅更简单、更小,而且还避免了任何 transient 变量和可变性的创建。事实上,如果您正在调用的函数的类型与结果有关,那么 while建筑将开始变得更加难以阅读。请尝试仅使用 whiles 来执行以下操作:
    def replicate(l: List[Int])(times: Int) = l.flatMap(x => List.fill(times)(x))

    然后继续定义一个执行相同操作的尾递归函数。

    更新:

    我听到你说:“嘿!那是作弊! foreach 既不是 while 也不是 tail-rec 电话”。哦真的吗?看看 Scala 对 foreach 的定义对于 Lists :
      def foreach[B](f: A => B) {
    var these = this
    while (!these.isEmpty) {
    f(these.head)
    these = these.tail
    }
    }

    如果您想了解更多关于 Scala 中的递归,请查看 this blog post .一旦你进入函数式编程,疯狂地阅读 Rúnar 的 blog post .更多信息 herehere .

    关于scala - 在Scala中避免while循环有什么好处吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18674743/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com