Option/Some/None和Try/Success/Failure出现的意义
在Scala中有一个非常重要的思想——避免null。很多Scala程序员都是Java程序员,Java中的null和空指针异常几乎可以说是无处不在。而在Scala中有一条非常重要的思想就是从意识中抹去有null关键字这回事。这也是Option/Some/None和Try/Success/Failure存在的意义。
微信公众号:大数据报文
Option/Some/None
可以简单的认为Some和None是Option的两种不同表现形式,如果Option中有内容,就是Some,如果没有内容就是None.而None一般是在Some取不到值的时候(比如空指针的时候),或者说程序有异常的时候才会取到None,但是None本身并不会携带任何异常信息。
def toInt(strNum: String):Option[Int] = {
try {
Some(Integer.parseInt(strNum.trim))
}catch {
case e: Exception => {
println(e.getMessge)//在try后打印异常信息,然后将None作为返回值返回
None
}
}
上面定义了一个方法,基本思想就是将本该返回的结果使用Some包裹一下,使用Some()或者None代替空指针的情况。但是None本质还是空指针啊,比如返回结果result调用get()方法的时候依然会有异常产生。
这里就牵扯到另外一个问题即Option对象如何取值的问题。
Option对象取值问题
上面提到了使用get方法,None.get仍然是会报空指针的,因为这是一种Java思想,在Scala中提供了三种不同的方式去获取Option对象的值。
1.getOrElse方式
这是一种简单而行之有效的方式,如果Option中有值就获取,没有就使用提供的默认值。
toInt("aa").getOrElse(0)
2.使用模式匹配的方式
toInt("234") match {
case Some(n) => println(s"$n")
case None => println("not a number")
}
3.使用foreach方法
本质上Some()中包含0个或者多个值,使用foreach方法是肯定行得通的。
toInt("12").foreach(println)
Try/Success/Failure
与Option/Some/None
类似,Success和Failure是Try的两种不同表现形式,如果成功表现为Success,如果失败表现为Failure。但是与Option/Some/None
不同的是,在Failure中会携带异常信息。
关于取值方面,与上面的Option一样支持三种方式。
//如果y传入的非0,会返回Success(结果)
//如果y传入的为0,会返回Failure(异常信息)
def divideXByY(x:Int,y:Int):Try[Int] = {
Try(x/y)
}
//取值跟Option一致
divideXByY(1,0).getOrElse(0) //如果抛出异常就是0,否则就是计算结果
//下面使用模式匹配的方式可以打印异常信息,这样处理会比上面优雅很多
divideXByY(1,2) match {
case Success(i) => println(s"Success, value is $i")
case Failure(e) => println(s"Failure, message is $e")
}
//另外一个例子。在进行数字转换的时候如果转换失败,也不会导致代码中断
def anotherDemo(x: String, y: String): Unit = {
val z = for {
a <- Try(x.toInt)
b <- Try(y.toInt)
} yield a * b
val answer = z.getOrElse(0) * 2
println(answer)
}
同时Try/Success/Failure是可以转化为Option/Some/None的。
Success("hello").toOption