私は末尾の再帰的メソッドを持つために約@tailrec
の注釈を使用して読んでいます。私はそれを説明する多くのリンクを見てきました。例えば、それは自己呼び出し関数のためにのみ機能し、オーバーライドされてはならない。@tailrecはどのように動作するのですか
どこでもcompiler optimizes
が言及されている。しかし、コンパイラはそれを尾を再帰的にするためにどのような魔法/コンセプトをしますか?以下の簡単な関数、コンパイラは何をするのかについて:
@tailrec def fact(acc: Int, n: Int): Int = {
if (n <= 1) acc
else fact(n * acc, n - 1)
}
fact(1,10)
私はそれはそれはそれを繰り返し呼び出し、最終的な値を返しループに変換するとはどういう意味しますか?ここで
基本的には、scalaコンパイラはコードをwhileループと同様にバイトコードに変換します。おそらく 'var acc = 1;のようなことをしています。 var n = 10; start:if(n <= 1)は、accを返します。else {acc = n * acc; n = n-1; goto start} 'を実行します。すべてのテールコールを身体の開始点に機械的に置き換えることが可能でなければなりません。 – huynhjl