方法评估不符合预期

时间:2013-09-14 21:30:17

标签: scala

下面的代码计算斐波纳契序列与特定数字的总和。

但是抛出了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)

2 个答案:

答案 0 :(得分: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时,你就不会停止。

答案 1 :(得分:2)

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

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

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

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

def fibonacci(i : Int) : Int = {
    println(i)
    i match {
        case 0 => 0
        case 1 => 1
        case _ => fibonacci(i - 1) + fibonacci(i - 2)
    }
}