41
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-01-26

#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を使ってスッキリさせませんか?

41
34
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?