69.scala编程思想笔记——使用Try转换异常
欢迎转载,转载请标明出处:http://blog.youkuaiyun.com/notbaron/article/details/50458765
源码下载连接请见第一篇笔记。
为了进一步降低对异常进行管理的代码量,Try会铺货所有异常,并且产生一个作为结果的对象。
Success和Failure 是Try的子类。而Try是在Scala2.10 中出现的,早起版本无法工作。
例如:
import com.atomicscala.AtomicTest._
import util.{Try, Success, Failure}
def f(i:Int) = Try(24/i)
f(24) is Success(1)
f(0) is "Failure(" +
"java.lang.ArithmeticException: " +
"/ by zero)"
def test(n:Int) =
f(n) match {
caseSuccess(r) => r
caseFailure(e) =>
s"Failed: ${e.getMessage}"
}
test(4) is 6
test(0) is "Failed: / by zero"
Failure和 Success与Either 的left和right相比,是更具描述性和更易于记忆的错误报告对象。
有个题外话:Double被0除不会产生异常,而是产生一个特殊的无穷大的对象。
Try有相应的措施来简化代码,即recover方法,可以接受任何异常,并将其转换为有效的结果,如下:
import com.atomicscala.AtomicTest._
import util.Try
import errors._
def f(n:Int) = Try(toss(n)).recover {
casee:Throwable => e.getMessage
}.get
def g(n:Int) = Try(toss(n)).recover {
caseExcept1(why) => why
caseExcept2(n) => n
caseExcept3(msg, d) => s"$msg $d"
}.get
f(0) is "OK"
f(1) is "Reason"
f(2) is "11"
f(3) is "Wanted: 1.618"
g(0) is "OK"
g(1) is "Reason"
g(2) is "11"
g(3) is "Wanted: 1.618"
Try 有相应的措施来简化代码,即recover方法,可以接受任何异常,并将其转换为有效的结果:
import com.atomicscala.AtomicTest._
import util.Try
import errors._
def f(n:Int) = Try(toss(n)).recover {
casee:Throwable => e.getMessage
}.get
def g(n:Int) = Try(toss(n)).recover {
caseExcept1(why) => why
caseExcept2(n) => n
caseExcept3(msg, d) => s"$msg $d"
}.get
f(0) is "OK"
f(1) is "Reason"
f(2) is "11"
f(3) is "Wanted: 1.618"
g(0) is "OK"
g(1) is "Reason"
g(2) is "11"
g(3) is "Wanted: 1.618"
其中Success对象将会原封不动地穿过recover,但是Failure对象将被铺货,并且与recover的match子句匹配。
根据需要,Try 可以产生一些非常简洁的错误检查和处理代码,如下:
import com.atomicscala.AtomicTest._
import util.Try
def intPercent(amount:Int, total:Int) =
Try(amount *100 / total).getOrElse(100)
intPercent(49, 100) is 49
intPercent(49, 1000) is 4
intPercent(49, 0) is 100
Scala以后的版本可能会包含对错误报告的处理机制的重新设计,我们希望新的的设计能够使程序员编写出更简单和更直观的错误处理代码。
还有第三方库可以帮助我们校验数据,就是scalaz库中的validation组件。