Option,Either和Try

Option,Either和Try

scala數據交互html

本文介紹在Scala 2.10中怎樣使用一種函數式的方式來處理數據交互,包括入參及返回值。java

  • Option: 解決null(空指針)問題api

  • Either: 解決返回值不肯定(返回兩個值的其中一個)問題app

  • Try: 解決函數可能會拋出異常問題函數

Option

API:http://www.scala-lang.org/api/2.10.0/index.html#scala.Optionspa

在Java中,當一個操做返回無效值或數據不存在時一般狀況下返回返回一個 null 。好比 servlet
request.getParameter("id") ,或id不存在將返回 nullMap<String, String> 也是,
data.get("dd") 當Key:dd不存在時也將返回 null 。一句話,在Java的世界,你須要隨時當心
NullPointerExceptionscala

如今,咱們再來看看Scala中的解決方案:Option。Option實際上有3個類型:Option、Some和None,
Some和None都是Option的子類型,Some和None。Option表示可選的值,它的返回類型是 scala.Some
scala.None 。Some表明返回有效數據,None表明返回空值。最經常使用的使用方式是把scala.Option
看成集合或單子(monad)使用,能夠調用它的map、flatMap、filter或foreach方法。這裏咱們來看看一
些例子:設計

scala> val name: Option[String] = Some(" name  ")
name: Option[String] = Some( name  )

scala> val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase }
upper: Option[String] = Some(NAME)

scala> println(upper getOrElse "-")
NAME

scala> upper.getres1: String = NAME

從這個簡單的例子能夠知道,Option做爲變量的類型,而它實際擁有的類型爲Some或None。在這裏把
Some(" name ") 換成 None 再試試:指針

scala> val name: Option[String] = None
name: Option[String] = None

scala> val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase }
upper: Option[String] = None

scala> println(upper getOrElse "-")
-

scala> upper.getjava.util.NoSuchElementException: None.get
    at scala.None$.get(Option.scala:313)
    at scala.None$.get(Option.scala:311)

咱們可使用 getOrElse 方法來獲取實際的數據,這個方法包含一個參數,當Option爲None時將返回傳
入的參數值。而對於Some,能夠直接使用 get 方法獲取實際的數據值; None是不能夠的。code

這裏,咱們在爲Option賦值時顯示的使用了Some或None類型,當使用Some時需求咱們保證數據有效(不可爲
null)。其實咱們可使用Option對象來進行賦值:

scala> val x: Option[String] = Option("name")x: Option[String] = Some(name)scala> val y: Option[String] = Option(null)y: Option[String] = None

scala> val x = Option("name")x: Option[String] = Some(name)scala> val a = Option(null)a: Option[Null] = None

使用Option的妙處在,使用Servlet時能夠以下:

val username = Option(request getParameter "username")val password = Option(request getParameter "password")val login_? = 
  for (
    un <- username;
    pwd <- password;
    isLogin <- login(un, pwd)) yield isLogin  // login方法登錄驗證成功返回truelogin_? match {  case Some(_) =>    // 登錄成功
    // redirect to ...
  case None =>    // 登錄失敗
    // 返回錯誤消息}

這裏,Option.apply 方法在 request.getParameter 返回null時將爲 username 賦值爲
None。由於Option實現了 map, filter, flatMap, foeach及toList 方法,咱們能夠在for靜達式
中使用它。

Either

API:http://www.scala-lang.org/api/2.10.0/index.html#scala.util.Either

程序設計中常常會有這樣的需求,一個函數(或方法)在傳入不一樣參數時會返回不一樣的值。返回值是兩個不相關
的類型,分別爲: LeftRight 。慣例中咱們通常認爲 Left 包含錯誤或無效值, Right
包含正確或有效值(這個和從小嚐到的左、右派分子定義相反啊!)

def readfile(): Either[IOException, String] = try {
  Right("羊八井好帥 ^_^!")
} catch {
  case e: IOException => Left(e)
}

println(readfile match {
  case Right(msg) => msg
  case Left(e) => e.getMessage
})

除了使用match case方式來獲取數據,咱們還能夠分別使用 .right.get.left.get 方法,當
然你須要使用 .isRight.isLeft 先判斷一下。Left或Right類型也有 filter, flatMap, <br />foreach, get, getOrElse, map 方法,它們還有 toOption, toSeq 方法,分別返回一個 Option
Seq

Try

API:http://www.scala-lang.org/api/2.10.0/index.html#scala.util.Try

在剛纔的 readfile 方法裏,咱們顯示使用了 try catch 語法。Scala 2.10提供了 Try 來更優
雅的實現這一功能。對於有可能拋出異常的操做。咱們可使用Try來包裹它。

y: scala.util.Try[Int] = Failure(java.lang.NullPointerException: null ...)
z: scala.util.Try[Int] = Success(27)

scala> val y: Try[Int] = Try{ throw new NullPointerException("null ...") }
y: scala.util.Try[Int] = Failure(java.lang.NullPointerException: null ...)

scala> val x: Try[Int] = Success{ 27 }
x: scala.util.Try[Int] = Success(27)
相關文章
相關標籤/搜索