1

下面的代码计算一个特定数字的斐波那契数列的总数。

但是会抛出 StackOverFlow 异常。当我在函数中检查 0 时,为什么会抛出这个异常?

object fibonacci extends Application {

def fibonacci(i : Int) : Int = {
    println(i)
    if(i == 0) 0
    if(i == 1) 1
    fibonacci(i - 1) + fibonacci(i - 2)
}

fibonacci(3)

}

错误 :

scala> fibonacci(3)
3
2
1
0
-1
-2
-3
-4
-5
-6
-7
-8
-9
.......


scala> fibonacci(3)
java.lang.StackOverflowError
        at .fibonacci(<console>:10)
        at .fibonacci(<console>:10)
        at .fibonacci(<console>:10)
        at .fibonacci(<console>:10)
4

2 回答 2

3
def fibonacci(i : Int) : Int = {
    println(i)
    if (i == 0) 0
    else if (i == 1) 1
    else fibonacci(i - 1) + fibonacci(i - 2)
}

没有这些else,当您达到 0 或 1 时,您不会停止。

于 2013-09-14T21:38:20.803 回答
2

Scala 会自动将函数的返回值评估为最后一条语句的计算值(这就是您不需要return关键字的原因)。

如果没有elses,您的两个if语句是独立语句,但不是函数中的最后一个语句。它们解析为一个值,但该值没有分配给任何东西,因此被丢弃,函数继续处理语句。

将 s 放入(根据@Marthelse的解决方案)可确保您使用由单个 if-else 链组成的单个语句来结束函数。整个语句(以及函数)的计算结果是选择和执行链的任何一个分支的结果。

match您还可以使用 a (也被视为单个语句)来实现您想要的效果:

def fibonacci(i : Int) : Int = {
    println(i)
    i match {
        case 0 => 0
        case 1 => 1
        case _ => fibonacci(i - 1) + fibonacci(i - 2)
    }
}
于 2013-09-14T23:09:30.337 回答