Scala.E或getOrElse方法

时间:2013-08-21 20:13:33

标签: scala either

为什么当我输入这个时一切正常?

Right(2).left getOrElse Right(4).left getOrElse Left("Error")

但是当我键入此编译失败?

Right[String, Int](2).left getOrElse Right[String, Int](4).left getOrElse Left[String, Int]("Error")

编译错误:

  

值getOrElse不是java.io.Serializable的成员
  println(RightString,Int.left getOrElse RightString,   Int.left getOrElse LeftString,Int)

所以我无法链接getOrElse方法调用

1 个答案:

答案 0 :(得分:8)

getOrElse的{​​{1}}签名是:

LeftProjection[A, B]

即。它期望参数是某种类型def getOrElse[AA >: A](or: ⇒ AA): AA ,它是AA的超类型。

在第一个示例中,您省略了类型注释,允许编译器推断A Nothing。然后,您提供了类型为A的参数。

因为LeftProjection[Nothing, Int]所有类型的子类型,Nothing通常是超类型!类型系统中的这种特殊情况意味着它几乎是偶然进行了类型检查。

但是,LeftProjection[Nothing, Int]String的最具体的常见超类型是LeftProjection[String, Int]


所以,如果你想链接Serializable,你需要一个可以采用另一个Either的方法,而不仅仅是Either[A, B]A

您似乎想要的方法如下所示:

B

(您可以类似地编写def leftOrElse[A, B](e1: Either[A, B], e2: => Either[A, B]): Either[A,B] = e1 match { case Left(a) => Left(a) case Right(b) => e2 } ,这是一个更常见的用例。)

如果你使用implicits将它作为扩展方法,这在语法上会变得更有用。

rightOrElse

因为这两个操作数都需要implicit class EitherOps[A, B](e1: Either[A, B]) { def leftOrElse(e2: => Either[A, B]): Either[A,B] = // as above } ,而不是Either[A, B]A(或其某些超类型),您可以链接B

Either