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(_) =>
}
}