scala數據交互html
本文介紹在Scala 2.10中怎樣使用一種函數式的方式來處理數據交互,包括入參及返回值。java
Option: 解決null(空指針)問題api
Either: 解決返回值不肯定(返回兩個值的其中一個)問題app
Try: 解決函數可能會拋出異常問題函數
API:http://www.scala-lang.org/api/2.10.0/index.html#scala.Optionspa
在Java中,當一個操做返回無效值或數據不存在時一般狀況下返回返回一個 null
。好比 servlet
中 request.getParameter("id")
,或id不存在將返回 null
。Map<String, String>
也是, data.get("dd")
當Key:dd不存在時也將返回 null
。一句話,在Java的世界,你須要隨時當心 NullPointerException
!scala
如今,咱們再來看看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靜達式
中使用它。
API:http://www.scala-lang.org/api/2.10.0/index.html#scala.util.Either
程序設計中常常會有這樣的需求,一個函數(或方法)在傳入不一樣參數時會返回不一樣的值。返回值是兩個不相關
的類型,分別爲: Left
和 Right
。慣例中咱們通常認爲 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
。
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)