00012 Scala Either

在之前的文章中我们提到了Option,scala中Option表示存在0或者1个元素,如果在处理异常的时候Option就会有很大的限制,因为Option如果返回None,那么我并不知道具体的异常到底是什么,这样scala引入了Either。

顾名思意,Either表示或者是这一个元素或者是那个元素。这样在异常处理的时候就非常有用了。

我们先看一下Either的定义:

sealed abstract class Either[+A, +B] extends Product with Serializable

它有两个子类Left和Right:

/** The left side of the disjoint union, as opposed to the [[scala.util.Right]] side.
 *
 *  @author <a href="mailto:[email protected]">Tony Morris</a>, Workingmouse
 */
final case class Left[+A, +B](@deprecatedName('a, "2.12.0") value: A) extends Either[A, B] {
  def isLeft  = true
  def isRight = false

  @deprecated("Use .value instead.", "2.12.0") def a: A = value
}

/** The right side of the disjoint union, as opposed to the [[scala.util.Left]] side.
 *
 *  @author <a href="mailto:[email protected]">Tony Morris</a>, Workingmouse
 */
final case class Right[+A, +B](@deprecatedName('b, "2.12.0") value: B) extends Either[A, B] {
  def isLeft  = false
  def isRight = true

  @deprecated("Use .value instead.", "2.12.0") def b: B = value
}

我们通过这两个子类从两个可能的元素中选择一种。

Either 概念的产生时间早于Scala。很长时间以来它被认为是抛出异常的一种替代方案。 为了尊重历史习惯,当Either 用于表示错误标志或某一对象值时,Left 值用于表示错误标志,如:信息字符串或下层库抛出的异常;而正常返回时则使用Right 对象。很明显,Either 可以用于任何需要持有某一个或另一个对象的场景中,而这两个对象的类型可能不同。

我们看下怎么用Either的常规使用:

再看一下Either怎么在代码中消除程序错误,将错误封装在Either中。

先看上面的例子,我们定义了一个addInts方法,接收两个String参数,并将其转换为Int。如果两个参数都是可以转换的字符串当然没问题,但是如果输入了一个无法转换的字符串就会报异常。

虽然异常有时候是好事情,但是异常会阻止程序的正常运行。我们看下怎么用Either来将其封装起来:

按照上面的设计,Either封装好了异常,不会影响程序的正常运行,而且可以返回具体的错误信息,实在是一个不错的设计方式。

最后更新于

这有帮助吗?