我正在阅读马丁·奥德斯基(Martin Odersky)的scala书。在第10章(组成和继承)中,此代码:
def spiral(nEdges: Int, direction: Int): Element = {
if (nEdges == 1) {
elem("+")
}
else {
println(s"nEdgesInside1=$nEdges")
val sp = spiral(nEdges - 1, (direction + 3) % 4)
def verticalBar = elem('|', 1, sp.height)
def horizontalBar = elem('-', sp.width, 1)
println(s"nEdgesInside2=$nEdges")
if (direction == 0)
(corner beside horizontalBar) above (sp beside space)
else if (direction == 1)
(sp above space) beside (corner above verticalBar)
else if (direction == 2)
(space beside sp) above (horizontalBar beside corner)
else
(verticalBar above corner) beside (space above sp)
}
}
我无法理解代码如何超出界限:
val sp = spiral(nEdges - 1, (direction + 3) % 4)
根据我的理解,
nEdges
在每次迭代中都会递减,调用spiral
函数,一旦达到1(即终止条件),它就会通过elem
函数创建对象。当我测试此代码并打印
nEdges
的值时,它会递减直到调用spiral
函数的行上方,然后在该行之后开始递增。谁能解释我这是怎么回事。提前致谢
最佳答案
基本上,这就是递归的工作方式。 edges
递减直到达到1,同时继续调用spiral
,生成更多的堆栈帧,每个堆栈帧都有自己的值nEdges
和direction
。一旦我们达到1,调用堆栈就开始释放,较旧的堆栈帧被破坏,这意味着这两个字段的较小值将被丢弃,以代替较高的堆栈帧中较高的值。
例如,使用递归阶乘计算的图像:
(©陈瑜。玉-http://jade-cheng.com/hpu/2012-spring/csci-2912/recursion/)
想象一下,n
代表nEdges
,您会发现它随每个方法调用而递减,并且当n = 0
时,我们开始展开,并在n
值较高的堆栈中越走越高。