-3

重複の可能性:
Scala でのリターン

Scala を使い始めたばかりで、よくわからない動作に遭遇しました。stackoverflow コミュニティが何らかの光を当ててくれることを願っています。

このテストの使用:

example(1,List(1))

このコードは期待どおりに機能します - 2 回目の反復で 0 が返されます。

def example(value: Int, list: List[Int]): Int = {
  if (list.isEmpty)
    return 0
  else
    return 1
  example(value - list.head, list.tail) + example(value, list.tail);
}

ただし、このコードはそうではありません。2 回目の反復で NoSuchElementException("head of empty list") がスローされます。

def example(value: Int, list: List[Int]): Int = {
  if (list.isEmpty)
    0
  else
    1
  example(value - list.head, list.tail) + example(value, list.tail);
}

違いは、2 番目の例では、関数の最後に別の式があるため、Scala は "0" と "1" が戻り値ではなく、評価される式であると想定していることです。明示的な「return」キーワードにより、最初の例が期待どおりに返されることは理にかなっています。

ただし、2 番目の例の if ステートメントの構文を考えると、"0" は評価される式ではなく、戻り値であることがコンパイラによって認識されると思います。そうでないのはなぜですか?

4

1 に答える 1

0

質問のその部分は完全に重複しているため、暗黙的な戻りについては、ここで回答を読む必要があります。

しかし、興味深い観察であるため、「コンパイラは、「0」は評価される式ではなく、むしろ戻り値であることに気付くと思います」というあなたの指摘に具体的に答えます。

簡単な答えはそれ0 表現であるということです...それはたまたまその評価が非常に単純な場合です。Scalaは、コードの処理方法を決定するときに、「労力を必要とする式」と「簡単な式」を区別しません。指示された方法で処理するだけです。

さらに重要なことに、Scalaコンパイラーあなたの意図を推測するビジネスに参入した場合、それはかなりクレイジーになり、コーディングがはるかに困難になります!

これが不要な理由を確認するために、投稿したコードを見てみましょう。

def example(value: Int, list: List[Int]): Int = {
  if (list.isEmpty)
    0
  else
    1
  example(value - list.head, list.tail) + example(value, list.tail);
}

あなたが言ったように、0and1ビットは実際には何もしていません。したがって、この架空のコンパイラは、「ねえ!これらを使ってできる唯一の興味深いことは、それらを返すことです!」と言うでしょう。したがって、彼らを帰らせます。これで、両側が戻るif/elseができました。つまり、list空の場合は戻り、空でない場合は戻ります。したがって、常に戻り、関数は終了します。

ちょっと待って!!if / else式の後に別の行があります!したがって、架空のコンパイラは、「ねえ!ここに戻ると、その行を実行することはありません!その行は非常に重要に見えます。実行できるように、戻るべきではないかもしれません」と言います。しかし、それは「ああ、いや!私が0またはを返さなければ1、それらは無意味です!私はそれらを返さなければなりません!」と気づきます。「しかし、その最後の行はまだそこにあります!」。「あぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁ!

したがって、コンパイラーが必要なものを推測しようとせず、代わりに指示されたとおりに実行する方がよい場合があります。

于 2012-09-25T01:13:51.897 に答える