Scalaでもtry-catchを使う方がよい事もある
環境 Scala 2.13.6
Scalaだと例外を常にTry
で処理しがちなので、反省メモ。
もちろん単純に例外出す可能性ある個所をTry
で包むのは問題ない。
困るのはTry[Either[L, R]]
みたいなネストを避けたい時。
refinedとかでよくある。
例えば以下は単純にString
をEither[String, PosInt]
に変換している。
import cats.implicits._ import eu.timepit.refined.api.RefType import eu.timepit.refined.types.numeric.PosInt import scala.util.Try def s2pi(s: String): Either[String, PosInt] = Try(s.toInt).toEither .leftMap(_.getMessage) .flatMap(RefType.applyRef[PosInt](_)) val etPiR = s2pi("1") // Right(1) val etPiL = s2pi("a") // Left(For input string: "a")
読みずらい!
まあ正直言うと、このくらいならまだマシで、実際コード書いているともっと複雑になる事も多々ある。
こういうTryとEitherのネストを避けようとするなら、以下のように書くのが断然読みやすい。
import eu.timepit.refined.api.RefType import eu.timepit.refined.types.numeric.PosInt import scala.util.Try def s2piVer2(s: String): Either[String, PosInt] = try RefType.applyRef[PosInt](s.toInt) catch { case t: Throwable => Left(t.getMessage) } val etPiV2R = s2piVer2("1") // Right(1) val etPiV2L = s2piVer2("a") // Left(For input string: "a")