35
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

scala.util.Tryを使いこなそう

1.とっても便利なTry

Scalaを使っていて、以下のような書き方をしてしまうことあるのでは無いでしょうか?

def sampleDBAccess(id:String):writeEntity = {
    try{
      //何か転けそうなselect
      DBAccessor.selectById(id)
    }catch{
      case notfound:EntityNotFoundException => Entity.empty
      case e:Throwable => throw e
    }
}

JavaとかCとかやってるとつい書いてしまう処理です。
これだと、Exception投げる処理が分散してしまって、どこでなげたっけ?あれ??となってしまったりします。
また、関数型的にかっこよくないなーって感じるかもしれません。
そこで!Scalaのscala.util.Tryです!

def sampleDBAccess(id:String):Try[writeEntity] = Try {
   DBAccessor.selectById(id).recover {case notfound:EntityNotFoundException => Success(Entity.empty) } 
}

こんな感じ。
TryはSuccess()とFailure()に分かれていて、こけたらFailureに勝手にExceptionいれてくれる優れものです。

2.実際にどうやって使うの?

サンプルを使って、実際に書いてみます。

2-1. 参照したデータを使う。

// ユーザー名からEntityを引っ張ってくる関数
def resolveByName(name:String):Try[User]

// 使い方
val ids = resolveByName("yusuke").map(_.id) // Try[id]がかえる。

// キャッチする場所
val ids = ids.recover({
    //特定のExceptionの場合復帰させるのであればここに書く
    case e:Throwable => throw e 
}).get

2-2. 参照したデータでさらに参照してみる。

// ユーザー名からEntityを引っ張ってくる関数
def resolveByName(name:String):Try[User]

def resolveByUserId(id:UserId):Try[UserData]

// 使い方
val ids = resolveByName("yusuke").flatMap(user =>  resolveByUserId(user.id)) // Try[UserData]がかえる。

Try[Try[xxxx]]となった場合にはSeq同様にFlatMapを使って1つにまとめることができます。
これを十分活用すれば、Exceptionをまとめて上の層に渡すことも可能です。

2-3 こけてもこけてないように見せたい

// ユーザー名からEntityを引っ張ってくる関数
def resolveByName(name:String):Try[User]

// 上記でもかきましたがgetOrElseでもみ消しましょう。
resolveByName("hoge").getOrElse(/*デフォルト値*/)

2−4 複数のTryを扱う。

def resolveByName(name:String):Try[User]

def createByUserId(id:UserId):Try[Message]

val message = for{
   u <- resolveByName("hoge")
   message <- createByUserId(u.id)
} yield message
//messageにTry[Message]がはいる。

3. 最後に

このような感じで、scala.util.Tryはコケても、アプリケーションまでコケさせなくしたり、任意にコケさせたりできます。
いままで、try-catchで書いていた人もでscala.util.Tryを使ってスッキリさせませんか?

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
35
Help us understand the problem. What are the problem?