在追Action的時候不小心認識了Either,(這樣寫起來怎麼有點花心感XD)
就趁機整理一下啦!
Either顧名思義就是不是這個就是那個(繞口令來著)
這樣是不是會讓你想起不是有(Some)就是沒有(None)的Option呢?
以下是相關的class以及他們的繼承關係.
sealed abstract class Option[+A] extends Product with Serializable final case class Some[+A](x: A) extends Option[A] case object None extends Option[Nothing] abstract final class Nothing extends Any
之前在處理error handling的時候有用過Option,
成功回傳Some,失敗就回傳None,
但其實會有些問題, 因為我們有時候會需要針對不同的失敗原因個別處理,
像是我們要從資料庫讀取某筆資料, 可能會因為網路問題, 或是資料庫過於忙碌等等因素造成失敗
或者是我們成功得到資料庫的回應但是該筆資料並不存在
把這些林林總總的狀況概括用None來表示其實會太簡略
這個情況下我們就可以使用Either,
以下是相關的class以及他們的繼承關係.
sealed abstract class Either[+A, +B] extends AnyRef final case class Left[+A, +B](a: A) extends Either[A, B] with Product with Serializable final case class Right[+A, +B](b: B) extends Either[A, B] with Product with Serializable他的值可以是類型A或類型B,
通常回傳Left是用來表示失敗,用Right表示成功
因為Action的部分有點複雜, 這邊就從playframework的OAuth library貼個簡單的範例.
def retrieveRequestToken(callbackURL: String): Either[OAuthException, RequestToken] = { val consumer = new DefaultOAuthConsumer(info.key.key, info.key.secret) try { provider.retrieveRequestToken(consumer, callbackURL) Right(RequestToken(consumer.getToken(), consumer.getTokenSecret())) } catch { case e: OAuthException => Left(e) } }再加上Left跟Right都是case class,
所以我們抓到結果之後可以簡單地用match處理回傳值
val reqTok = retrieveRequestToken("localhost:9000/callback") reqTok match { case Right(tok) => // success, continue case Left(ex) => // fail to get request token, dothing }大概是這樣!
另外再補充一些細節,
1. sealed
被加上sealed關鍵字的類別, 只能被定義在同一個原始碼檔案的類別繼承.
2. Option[+A]
是covariance的概念, 指的是D如果是A的子類別, 則Option[D]也是Option[A]的子類別
ref:
- Either
- Left
- Option
- 探索Playframework: 如何正確使用thread pool
No comments:
Post a Comment