Scala の例外処理について調べたメモ(try-catch, Try[T])

    Scala には例外処理の書き方としては、

    • try, catch,finally
    • Option 型 Try

    の2つがある.

    それぞれ、実際に実装してどんな感じか調べてみました.

    try-catch

    try-catch で例外を処理する方法. これは、Java における例外処理と同じ.

    以下のようなコードを書いた. これを、もう一つの Try[T] で書き換える.

    object TryCatch {
      def main(args: Array[String]) {
        try {
          val result = divide(0)
          show(result)
        } catch {
          case e: Exception =>
        }
      }
    
      def divide(num: Int): Double = {
        try {
          val result = 1/num
          result
        }
        catch {
          case e: Exception =>      
            println("Failure!!")
            throw e
        }
      }
    
      def show(result: Double): Double =  {
        println(result)
        result
      }
    }

    Try[T]

    このスタイルは、try-catch に比べて以下のようなメリットがある.

    • 複数の例外を紡いで処理を書いていくときに、正常系と異常系を綺麗に分 けてかいていくことができる(for 分とかで)
    • つまり、コードが綺麗にかける.

    import scala.util.{Try, Success, Failure} を import して利用する.

    object TryCatch {
      def main(args: Array[String]) {
        val result = divide(0)
        result match {
          case Success(v) => show(v)
          case Failure(e) => 
        }
      }
    
      def divide(num: Int): Try[Double] = Try {
        val result = Try{1/num}
        result match {
          case Success(v) => v
          case Failure(e) =>
            println("Failure!!")
            throw e
        }
      }
    
      def show(result: Double): Try[Double] = Try {
        println(result)
        result
      }
    }

    もっと Monadic に!!

    main 関数は、以下のように flatMap や for 文を利用して書き換えることができる. この書き換えが Monadic なところなのだけれども、理解不足でこれ以上解説できません.

    def main(args: Array[String]) {
      val result = for {
        result  <- divide(0)
        result2 <- show(result)
      } yield result2
    }

    try-catch が手続的なのに対して、flatMap をつかうと、ずっと宣言的に見える.

    def main(args: Array[String]) {
      divide(0).flatMap( result => show(result) )
    }

    以上、Happy Hacking!!

    Special Thanks