webネタ

技術系ブログ。web系SE。1988。♂。@rhong_

Scalaのリファクタリング小ネタ (例外)

例外時にデフォルトを取るような場合

// not bad
try { "a".toInt } catch { case e: Throwable => 0 }
// good
Try { "a".toInt }.getOrElse(0)

例外をOptionで取る場合

// not bad
try { Some("a".toInt) } catch { case e: Throwable => None }
// good
Try { "a".toInt }.toOption
// good
allCatch.opt { "a".toInt }

例外をEitherで取る場合

// not bad
try { Right("a".toInt) } catch { case e: Throwable => Left(e) }
// good
allCatch.either { "a".toInt }

Tryで取りたいがfinallyもしたい

// not bad
Try { "a".toInt } match { case t => println("logged"); t }
// good?
allCatch.andFinally { println("logged") }.withTry { "a".toInt }

関係ないけどOptionはIterableになるのか

// OptionにはIterableへのimplicitが定義してある
scala> Option(1).zip(Seq(2))
res14: Iterable[(Int, Int)] = List((1,2))

// こういうことも
scala> for {
     |   s <- Seq("1", "two", "3")
     |   i <- Try(s.toInt).toOption
     | } yield i
res13: Seq[Int] = List(1, 3)

try-catchよりTryかCatchを使うと大体の場合短く分かりやすく書ける気がする。