2017-07-31 13 views
-1

なぜScalaの再帰は、0Pythonで再帰とScalaの

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

戻っていますか?

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

どのようにPythonとScalaは再帰を処理し、ネストされたアクティベーションレコードを管理しますか?

答えて

2

スカラでは、ブロックの値がの最後の文の値に評価されます。たとえば、あなたが書くことができます。

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

myVal9に評価されます。

同様に、あなたのelseブロックは(明示的なreturnキーワードはありませんにもかかわらず)foo(id - 1)から返された値に評価され、そのため全体のメソッド本体の値は限りelseブロックに到達したように、その値に評価されます( if文全体がfoo(id - 1)の結果に評価され、そのifがメソッド本体の最後の(そして唯一の)文であり、それがメソッドの戻り値となります。

あなたにも最初returnキーワードをドロップすることができます。

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

、それは単にケースではありません。 return文だけがメソッドの戻り値を示します。何も返さない場合はNoneが返されます。

0

あなたはどちらかelse句にreturnを追加する必要があります。

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

    return foo(id - 1) 

またはような何か:あなたのelse句でreturnが必要

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

このようにして、ScalaとPythonの両方のソリューションが同じ結果を返しますが、なぜ2番目のreturn文を追加する必要があるのでしょうか?これらの再帰の処理方法の違いはどちらですか? – w4bo

+2

@ w4bo、Scalaは最後の式を暗黙的に*返します。 Pythonはそうではありませんので、*明示的* returnを追加する必要があります。再帰は同じように扱われる可能性が高い。 – cdlane

1

を:

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

これはreturnであなたは基本的です関数に値を代入する。そして、2つ目は、Pythonがreturnキーワードを必要とする間に、Scalaは最後のステートメントで評価を行います。したがって、foo(0)が0を返す場合、foo(0)はの値を含むになります。はありません。は返されません。この関数はデフォルトでNoneになります。

returnを使用すると、foo(id-1)の値がfoo(id)に割り当てられます。しかし、それは何ですか?これは、foo(id-1)の値を取得するために再帰的になるので、関数を実行する必要があります。

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

あなたはid/nhereの着実な減少を見ることができます:あなたはreturnと言い換えれば0になるまでこれが何度も発生します。