第三章 函数式编程中的异常处理

一. 函数式编程中的异常处理

(本章将自己实现scala标准库中的Option,Either)

  1. 异常的优点和劣势
    (1)函数抛出异常导致成为偏函数

    // 偏函数版mean,没有对所有输入做定义,比如对空的seq会抛出异常
    // 如果函数对所有输入都能返回Double,就是完全函数
    // 因此,为了改造成纯函数,可以把抛出异常,改为Double类型的某个特殊值,比如Double.NaN。但是这样,函数的调用者就必须知道如何处理这个特殊的返回值。由于特殊情况的存在,也就破坏了引用透明
    // 所以,接下来设计一种推迟返回值获取,来替代异常抛出的Option类
    def mean(xs:Seq[Double]):Double = {
    if (xs.isEmpty)
      throw new ArithmeticException("mean of empty list!")
    else
      xs.sum/xs.length
    }
    

(2)构造Option类族,包装结果
scala sealed trait Option[+A] case class Some[+A](get:A) extends Option[A] case object None extends Option[Nothing]
(3)改造mean函数为纯函数
scala /**利用Option类包装结果*/ def mean2(xs:Seq[Double]):Option[Double] = { if(xs.isEmpty) None else Some(xs.sum/xs.length) }
2. Either对异常处理
(1)Option不能表现出异常情况下发生了什么,只会返回一个None。Either作为对Optiond的扩展,可以跟踪失败原因
(2)Right和Left是Either的两个子类,Right表示结果正确,Left表示结果错误

```scala
  def mean(xs:IndexedSeq[Double]):Either[Exception,Double] = {
    try Right(1/0)
    catch {
      case e:Exception => Left(e)
    }
  }
```
posted @ 2017-03-02 11:36  moon_lord  阅读(966)  评论(0编辑  收藏  举报