TL;DR
try~catch内で値を返す再帰関数を書くには、scala.util.Tryを使う。説明
Scalaでは末尾再帰関数は最適化してくれるし、それをtailrecアノテーションでチェックすることができます。(最適化が効かない場合にコンパイルエラーが出るようになる)
@scala.annotation.tailrec def f(n: Int): Int = { ... // (略) f(n - 1) }ただこれ、try~catchを付けて、そこで値を返そうとするとうまくいかないんですよね~
@scala.annotation.tailrec def f(n: Int): Int = { try { ... // (略) f(n - 1) } catch { // どの場合も返す型は正しいものとする } }
scalac Main.scala Main.scala:3: error: could not optimize @tailrec annotated method f: it contains a recursive call not in tail position def f(n: Int): Int = {エラーメッセージも正しくなくてなんだこりゃって感じですが、stackoverflowに回答がありました。
何度も回答がEditされていますが、その一番下。try~catch節ではなく、scala.util.tryを用いることで回避できるようです。
@scala.annotation.tailrec def f(n: Int): Int = { scala.util.Try(例外の出る処理内容) { case Success(処理の返り値) => ... case Failure(e: 例外の型) => case Failure(e: 例外の型) => } }
知っていて最初からこれで書けば面倒くさいことはないんだけど…Scala、あちこち珍妙なとこあるよな。
0 件のコメント:
コメントを投稿