我正在学习Scala编程。我在函数主题中。
def sumOfInts(a: Int, b: Int): Int = {
if(a>b) 0 else a + sumOfInts(a+1,b)
}
println(sumOfInts(1,5)
程序的输出为15,怎么可能是15?谁能解释一下它是如何得到15的?
答案 0 :(得分:3)
让我们逐步了解调用它时会发生什么。
第一个sumOfInts
用a = 1,b = 5调用。 a
不超过b
,因此我们使用分支a + sumOfInts(a+1,b)
。 a
是1,所以我们有1 + sumOfInts(2, 5)
。按照这种模式,我们最终得到
1 + 2 + sumOfInts(3,5)
1 + 2 + 3 + sumOfInts(4,5)
1 + 2 + 3 + 4 + sumOfInts(5,5)
1 + 2 + 3 + 4 + 5 + sumOfInts(6, 5)
然后使用a=6
,a>b
为真,因此sumOfInts(6,5)
返回0
。因此,最终的调用堆栈如下所示:
1 + 2 + 3 + 4 + 5 + 0
哪个给了我们15。
答案 1 :(得分:2)
我将以不太密集的方式放置行号,以便更轻松地引用它们
1: def sumOfInts(a: Int, b: Int) = {
2: if (a > b) {
3: 0
4: } else {
5: a + sumOfInts(a+1, b)
6: }
}
如果仔细观察,您会发现sumOfInts
会自己调用-在第5行。此技术称为递归-您可能希望很好地理解它,因为它在许多算法和方法中都可以找到。和访谈问题:)但是简单地说,当函数进行一些计算时,递归会使用稍微修改的参数调用自身,然后将计算结果与自调用(称为递归调用)的结果“合并”。
在这种特殊情况下,所有这些“计算,递归,合并”都发生在第5行:
a
的值,sumOfInts(a+1, b)
现在,为了在某个时候真正完成,每个递归函数必须具有两个属性:
a+1
会这样做,我认为理论足够:)让我们跟踪函数并查看结果。我将用“替代”函数来迭代调用-实际上,这实际上是编译器/运行时可用来优化代码的技术之一,但即使对于人类,它也是非常有用的:)
1st call: a=1, b=5, a < b => 1 + sumOfInts(1+1, 5)
2nd call: a=2, b=5, a < b => 1 + 2 + sumOfInts(2+1, 5)
3rd call: a=3, b=5, a < b => 1 + 2 + 3 + sumOfInts(3+1, 5)
4th call: a=4, b=5, a < b => 1 + 2 + 3 + 4 + sumOfInts(4+1, 5)
5th call: a=5, b=5, a = b => 1 + 2 + 3 + 4 + 5 + sumOfInts(5+1, 5)
6th call: a=6, b=5, a > b => 1 + 2 + 3 + 4 + 5 + 0 = 15