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=============