■ はじめに
Scala の 例外処理について扱う。 基本、Javaに近いが、Scala特有の機能もある。 なお、Option / Either については、以下の関連記事を参照のこと
Scala ~ 基本編 / Option型 ~
https://dk521123.hatenablog.com/entry/2023/03/09/000000
Scala ~ 基本編 / Either型 ~
https://dk521123.hatenablog.com/entry/2023/08/02/132315
目次
【1】try / catch / finally 【2】例外クラス定義 【3】scala.util.Try 例1:Hello World 例2:日付変換 例3:日付変換 - 2
【1】try / catch / finally
* Javaと比較して、catch が若干違うだけで 他は同じように書ける
サンプル
object Hello { def main(args: Array[String]): Unit = { try { val result = 1 / 0 } catch { // catch は若干違う (rethrowは同じ) case e: Exception => throw e } finally { // finally も Javaと同じ println("Done!") } } }
【2】例外クラス定義
object DemoExceptions { class Demo1Exception extends RuntimeException class Demo2Exception extends RuntimeException }
【3】scala.util.Try
* まずは、サンプルをみてみるのが理解が早いかも、、、
https://github.com/scala/scala/blob/2.13.x/src/library/scala/util/Try.scala
例1:Hello World
// Tryを使うには、import が必要 import scala.util.Try object DemoExceptions { class DemoException extends RuntimeException } object Utils { import DemoExceptions._ def sum(a: Int, b: Int): Int = { if (a < 0 || b < 0) { throw new DemoException } a + b } } object Hello { import DemoExceptions._ // ★注目(特に Try { ... } 部分)★ private def demoTry(valueA: Int, valueB: Int): Try[Int] = Try { Utils.sum(valueA, valueB) } def main(args: Array[String]): Unit = { try { val result1 = demoTry(1, 1) println(result1) println(result1.getOrElse(-1)) val result2 = demoTry(1, -1) println(result2) println(result2.getOrElse(-1)) } catch { case e: DemoException => throw e } finally { println("Done!") } } }
出力結果
Success(2) 2 Failure(DemoExceptions$DemoException) // 補足参照 -1 Done!
補足
catchで rethrowしている作りだが、 そもそも例外にならずに catchに来ていない
例2:日付変換
import scala.util.{Failure, Success, Try} object Hello { def main(args: Array[String]): Unit = { val target = "2013-07-06" Array("yyyy/MM/dd", "yyyy-MM-dd").foreach(x => { val format = new java.text.SimpleDateFormat(x) // ★注目★ val result = Try(format.parse(target)) match { case Failure(e) => Left(e) case Success(v) => Right(v) } println(result.getOrElse("None")) }) } }
出力結果
None Sat Jul 06 00:00:00 JST 2013
例3:日付変換 - 2
import java.util.Date import scala.util.Try object Hello { def main(args: Array[String]): Unit = { val targets = Array("2013-07-06", "20130706", "2013.07.06") targets.zipWithIndex.foreach { case(target:String, index:Int) => { val result = getDate(target) // [0] Sat Jul 06 00:00:00 JST 2013 // [1] Sat Jul 06 00:00:00 JST 2013 // [2] None println(s"[${index}] ${result.getOrElse("None")}") } } } private def getDate(target: String): Option[Date] = { val dateFormats = Array("yyyy/MM/dd", "yyyy-MM-dd", "yyyyMMdd") dateFormats.foldLeft[Option[Date]](None) { (parsed, dateFormat) => val format = new java.text.SimpleDateFormat(dateFormat) // ★注目★ parsed.orElse(Try(format.parse(target)).toOption) } } }
参考文献
https://qiita.com/takayahilton/items/63f00762116b6d6c7f98
https://www.baeldung.com/scala/exception-handling
関連記事
Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Scala ~ 基本編 / Either型 ~
https://dk521123.hatenablog.com/entry/2023/08/02/132315
Scala ~ 基本編 / Option型 ~
https://dk521123.hatenablog.com/entry/2023/03/09/000000
Scala ~ 基本編 / 日付・日時 ~
https://dk521123.hatenablog.com/entry/2023/03/08/000000