ScalaにはEitherというキーワードがあります。
Eitherでは、LeftとRightのどちらか一方の値を持ちます。
異常系の場合にLeftにエラーメッセージ内容、正常形の場合はRightに処理結果を入れる、といった使い方が多いようです。
Eitherをforeachで扱う
EitherもOptionと同じようにforeachメソッドを使用して値にアクセスすることができます。
foreachを使うとRightとの時のみ処理を実施し、Leftの時は何もしません。
Either foreachのサンプル
def main(args: Array[String]) : Unit = { val r : Either[String, Int] = Right(1) r.foreach(println) // =>1 val l : Either[String, Int] = Left("Error") l.foreach(println) // Leftのため処理は行われない }
mapで扱う
こちらもOptionと同じようにmapを使って値を変換することができます。
Either mapのサンプル
def main(args: Array[String]) : Unit = { val r : Either[String, Int] = Right(1) val l : Either[String, Int] = Left("Error") // 値がRightの場合、実行される println(r.map(_ * 2 )) // => Right(2) // 値がLightの場合は、何も実行されず、元の値が返される println(l.map(_ * 2 )) // => Left(Error) // 明示的にLeftに対して処理をしたい時 println(r.left.map(_ + "!" )) // => Right(1) ... 値がLeftでない時はRightの値を返す println(l.left.map(_ + "!" )) // => Left(Error!) ... 値がLeftの時は処理が実行される }
flatMapで扱う
flatMapも同様に扱うことができます。
Either flatMapのサンプル
def main(args: Array[String]) : Unit = { val r : Either[String, Int] = Right(1) val l : Either[String, Int] = Left("Error") // 値がRightの場合、実行される println(r.flatMap(calc)) // => Right(2) // 値がLightの場合は、何も実行されず、元の値が返される println(l.flatMap(calc)) // => Left(Error) // 明示的にLeftに対して処理をしたい時 println(r.left.flatMap(plusExclamation)) // => Right(1) ... 値がLeftでない時はRightの値を返す println(l.left.flatMap(plusExclamation)) // => Left(Error!) ... 値がLeftの時は処理が実行される } def calc(i : Int) : Either[String, Int] = { Right(i * 2) } def plusExclamation(str : String) : Either[String, Int] = { Left(str + "!") }
getOrElseで値を取り出す
EitherにもOptionと同様にgetOrElseメソッドを使用することができます。
Either getOrElseのサンプル
def main(args: Array[String]) : Unit = { val r : Either[String, Int] = Right(1) val l : Either[String, Int] = Left("Error") // Rightの時は、その値が取り出される println(r.getOrElse(0)) // => 1 // Leftの時は、引数に渡したデフォルト値が返される println(l.getOrElse(0)) // => 0 }
match文で扱う
こちらもOptionと同様、match文で値を扱うことも可能です。
Either match文のサンプル
def main(args: Array[String]) : Unit = { val r : Either[String, Int] = Right(1) r match { case Right(v) => println(v) case Left(_) => } }