2017-08-13 58 views
3

我正在閱讀Martin Odersky撰寫的scala書。在第10章(成分組合及繼承),在此代碼:Scala書籍的Scala遞歸解釋

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) 

Accoording我的理解,nEdges是越來越減少。在每次迭代調用函數spiral,一旦達到1(即終止條件),它將通過elem函數創建對象。

當我測試這個代碼並打印nEdges的值時,它會遞減,直到上面的函數調用spiral函數,並且在那行之後它開始遞增。任何人都可以向我解釋這是怎麼發生的。

在此先感謝

回答

3

這基本上是遞歸的工作原理。 edges得到遞減,直到它達到1,並且在這樣做的過程中,它一直呼叫spiral,它產生更多的堆棧幀,每個堆棧幀具有它自己的值nEdgesdirection。一旦我們達到1,調用堆棧開始展開,舊的堆棧框架被破壞,這意味着這兩個字段的較小值會被丟棄,而不是堆棧幀中更高的值,在那裏它們具有更高的值。

例如,以遞歸階乘計算的這一形象:

Factorial recursive

(©陳羽玉 - http://jade-cheng.com/hpu/2012-spring/csci-2912/recursion/

試想一下,n代表nEdges,你看,它的遞減與每個方法調用,並且當n = 0,我們開始展開並且越往上越高,其中n具有更高的價值。