我正在阅读马丁·奥德斯基(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,生成更多的堆栈帧,每个堆栈帧都有自己的值nEdgesdirection。一旦我们达到1,调用堆栈就开始释放,较旧的堆栈帧被破坏,这意味着这两个字段的较小值将被丢弃,以代替较高的堆栈帧中较高的值。

例如,使用递归阶乘计算的图像:

scala - Scala书中的Scala递归说明-LMLPHP

(©陈瑜。玉-http://jade-cheng.com/hpu/2012-spring/csci-2912/recursion/

想象一下,n代表nEdges,您会发现它随每个方法调用而递减,并且当n = 0时,我们开始展开,并在n值较高的堆栈中越走越高。

10-02 03:28