为什么当我输入这个时一切正常?
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
方法调用
答案 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