Scala avoid nulljava
在Java裏, NullPointerException不知道會在何時發生,致使代碼處處都是判斷null的狀況。好比以下例子,git
val stateCapitals = Map( "Alabama" -> "Montgomery", "Alaska" -> "Juneau", "Wyoming" -> "Cheyenne") println("Get the capitals wrapped in Options:") println("Alabama: " + stateCapitals.get("Alabama")) println("Wyoming: " + stateCapitals.get("Wyoming")) println("Unknown: " + stateCapitals.get("Unknown")) println("Get the capitals themselves out of the Options:") println("Alabama: " + stateCapitals.get("Alabama").get) println("Wyoming: " + stateCapitals.get("Wyoming").getOrElse("Oops!")) println("Unknown: " + stateCapitals.get("Unknown").getOrElse("Oops2!"))
輸出打印,github
C:\WorkSpace5-gitosc\scala-showcase\src\main\java\com\usoft2>scala main3.scalashell
Get the capitals wrapped in Options:編程
Alabama: Some(Montgomery)api
Wyoming: Some(Cheyenne)數組
Unknown: Noneapp
Get the capitals themselves out of the Options:編程語言
Alabama: Montgomeryide
Wyoming: Cheyenne
Unknown: Oops2!
爲了讓全部東西都是對象的目標更加一致,也爲了遵循函數式編程的習慣,Scala鼓勵你在變量和函數返回值可能不會引用任何值的時候使用Option類型。在沒有值的時候,使用None,這是Option的一個子類。若是有值能夠引用,就使用Some來包含這個值。Some也是Option的子類。
None被聲明爲一個對象,而不是一個類,由於咱們只須要它的一個實例。這樣,它多少有點像null關鍵字,但它倒是一個實實在在的,有方法的對象。
Option類型的值一般做爲Scala集合類型(List,Map等)操做的返回類型。好比Map的get方法:
scala> val capitals = Map("France"->"Paris", "Japan"->"Tokyo", "China"->"Beijing") capitals: scala.collection.immutable.Map[String,String] = Map(France -> Paris, Japan -> Tokyo, China -> Beijing) scala> capitals get "France" res0: Option[String] = Some(Paris) scala> capitals get "North Pole" res1: Option[String] = None scala>
Option有兩個子類別,Some和None。當程序回傳Some的時候,表明這個函式成功地給了你一個String,而你能夠透過get()函數拿到那個String,若是程序返回的是None,則表明沒有字符串能夠給你。
在返回None,也就是沒有String給你的時候,若是你還硬要調用get()來取得 String 的話,Scala同樣是會拋出一個NoSuchElementException異常給你的。
咱們也能夠選用另一個方法,getOrElse。這個方法在這個Option是Some的實例時返回對應的值,而在是None的實例時返回傳入的參數。換句話說,傳入getOrElse的參數其實是默認返回值。
scala> capitals get "North Pole" get warning: there was one feature warning; re-run with -feature for details java.util.NoSuchElementException: None.get at scala.None$.get(Option.scala:344) at scala.None$.get(Option.scala:342) ... 33 elided scala> capitals get "France" get warning: there was one feature warning; re-run with -feature for details res3: String = Paris scala> (capitals get "North Pole") getOrElse "Oops" res4: String = Oops scala> capitals get "France" getOrElse "Oops" res5: String = Paris scala>
提示
Scala程序使用Option很是頻繁,在Java中使用null來表示空值,代碼中不少地方都要添加null關鍵字檢測,否則很容易出現NullPointException。所以Java程序須要關心那些變量多是null,而這些變量出現null的可能性很低,但一但出現,很難查出爲何出現NullPointerException。
Scala的Option類型能夠避免這種狀況,所以Scala應用推薦使用Option類型來表明一些可選值。使用Option類型,讀者一眼就能夠看出這種類型的值可能爲None。
實際上,多虧Scala的靜態類型,你並不能錯誤地嘗試在一個可能爲null的值上調用方法。雖然在Java中這是個很容易犯的錯誤,它在Scala卻通不過編譯,這是由於Java中沒有檢查變量是否爲null的編程做爲變成Scala中的類型錯誤(不能將Option[String]當作String來使用)。因此,Option的使用極強地鼓勵了更加彈性的編程習慣。
在Scala裏Option[T]其實是一個容器,就像數組或是List同樣,你能夠把他當作是一個可能有零到一個元素的List。
當你的Option裏面有東西的時候,這個List的長度是1(也就是 Some),而當你的Option裏沒有東西的時候,它的長度是0(也就是 None)。
scala> val map1 = Map("key1" -> "value1") map1: scala.collection.immutable.Map[String,String] = Map(key1 -> value1) scala> val value1 = map1.get("key1") value1: Option[String] = Some(value1) scala> val value2 = map1.get("key2") value2: Option[String] = None scala> def printContentLength(x: Option[String]) { | for (c <- x) { | println(c.length) | } | } printContentLength: (x: Option[String])Unit scala> printContentLength(value1) 6 scala> printContentLength(value2) scala>
在函數式編程中有一個核心的概念之一是轉換,因此大部份支持函數式編程語言,都支持一種叫map()的動做,這個動做是能夠幫你把某個容器的內容,套上一些動做以後,變成另外一個新的容器。如今咱們考慮如何用Option的map方法實現length: xxx的輸出形式:
先算出 Option 容器內字符串的長度
而後在長度前面加上 「length: 「 字樣
最後把容器走訪一次,印出容器內的東西
scala> val map1 = Map("key1" -> "value1") map1: scala.collection.immutable.Map[String,String] = Map(key1 -> value1) scala> val value1 = map1.get("key1") value1: Option[String] = Some(value1) scala> value1.map(_.length).map("length: " + _).foreach(println) length: 6 scala> value1.map("length: " + _.length).foreach(println) length: 6 scala>
轉載請註明做者Jason Ding及其出處
GitCafe博客主頁(http://jasonding1354.gitcafe.io/)
Github博客主頁(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡書主頁(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)
Google搜索jasonding1354進入個人博客主頁
=============END=============