成功した時はSuccessにラップして返し、例外時はFailureでラップして返す。いずれもscala.util.Tryのサブ型である。
scala> import scala.util._
import scala.util._
scala> case class ZeroLengthException(name:String) extends Exception(s"$name is zeo length")
defined class ZeroLengthException
scala> case class PrefixInvalidException(name: String) extends Exception(s"$name's prefix is invalid")
defined class PrefixInvalidException
scala> def getNameLength(name: String): Try[Int] = Try{
| name match {
| case name if name.size == 0 => throw ZeroLengthException(name)
| case name if name.startsWith("a") == false => throw PrefixInvalidException(name)
| case name => name.size
| }
| }
getNameLength: (name: String)scala.util.Try[Int]
scala> getNameLength("")
res0: scala.util.Try[Int] = Failure(ZeroLengthException: is zeo length)
scala> getNameLength("xbc")
res1: scala.util.Try[Int] = Failure(PrefixInvalidException: xbc's prefix is invalid)
scala> getNameLength("abc")
res2: scala.util.Try[Int] = Success(3)
とりあえずFailureの時はNothingという文字列にしてしまう。
scala> def showNameLength(nameLength: Try[Int]) =
| println("length = " + nameLength.map(_.toString).getOrElse("Nothing"))
showNameLength: (nameLength: scala.util.Try[Int])Unit
scala> showNameLength(getNameLength(""))
length = Nothing
scala> showNameLength(getNameLength("xbc"))
length = Nothing
scala> showNameLength(getNameLength("abc"))
length = 3
scala> def showNameLength(nameLength: Try[Int]) = {
| val msg = nameLength.map{
| e => s"length = $e"
| }.recover{
| case ex: ZeroLengthException => "zero length"
| case ex: PrefixInvalidException => "prefix invalid"
| }.get
| println(s"length = $msg")
| }
showNameLength: (nameLength: scala.util.Try[Int])Unit
使ってみる
scala> showNameLength(getNameLength(""))
length = zero length
scala> showNameLength(getNameLength("xbc"))
length = prefix invalid
scala> showNameLength(getNameLength("abc"))
length = length = 3
どういう時に使えるか、失敗する可能性がある処理の戻リ値として表現可能。呼び出し元のどこかで例外時のケースの処理を考慮した処理を実装させることができる。