2017-07-31 84 views
-1

爲什麼這斯卡拉遞歸遞歸在Python和Scala

def foo(id:Int): Int = { 
    if (id == 0) { return id } else { foo(id - 1) } 
} 
foo(2) 

回報0,而這條巨蟒遞歸返回None

def foo(id): 
    if id == 0: 
     return id 
    else: 
     foo(id - 1) 
foo(2) 

Python和Scala如何處理遞歸和管理嵌套的激活記錄?

回答

2

在Scala中,它是最後一條語句任何塊被評估爲價值。例如,你可以寫:

val myVal = { 
    val t = 1 
    val r = 8 
    t + r 
} 

這裏,myVal將評估爲9

同樣,你else塊評估從foo(id - 1)(即使沒有明確的return關鍵字)返回的值,因此整個方法體的值將作爲長期評估,以該值作爲達到else塊(整個if語句將被評估到foo(id - 1)的結果,因爲這if是在方法體中最後一個(也是唯一一個)聲明 - 這將是該方法的返回值)。

可以刪除第一return關鍵字以及:

def foo(id:Int): Int = { 
    if (id == 0) id else foo(id - 1) 
} 

在Python,這根本就不是這樣;只有return語句表示方法的返回值。如果您不返回任何內容,則返回None

0

你要麼需要一個return添加到else條款:

def foo(id): 
    if id == 0: 
     return id 

    return foo(id - 1) 

或做類似:

def foo(id): 
    return id if id == 0 else foo(id - 1) 
+0

我知道這樣Scala和Python解決方案都會返回相同的結果,但爲什麼我需要添加第二個return語句?這些遞歸處理的方式有哪些不同? – w4bo

+2

@ w4bo,Scala執行* implicit *返回最後一個表達式。 Python不會,所以我們必須添加一個* explicit * return。遞歸可能處理相同。 – cdlane

1

您需要returnelse條款:

def foo(id): 
    if id == 0: 
     return id 
    return foo(id - 1) 

這是與return你是基本的給函數分配一個值。第二,Scala在上一條語句中進行評估,而Python需要return關鍵字。所以,如果foo(0)返回0,foo(0)然後將包含返回的0。由於什麼值,函數不具有任何價值,其默認爲None

通過使用return,您可以將foo(id-1)的值賦值爲foo(id)。但是它是什麼?這是遞歸的地方,因爲要得到foo(id-1)的值,它必須運行該函數。出現這種情況一遍又一遍,直到你得到0。換句話說與return

foo(n) = foo(n-1) = foo((n-1)-1) = foo(n-2) = ... = foo(n-n) = foo(0) = 0 

你可以看的id/nhere穩步下降。