为什么当我输入这些时一切正常?
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")
编译错误:
value getOrElse is not a member of java.io.Serializable
println(RightString, Int.left getOrElse RightString, Int.left getOrElse LeftString, Int)
所以我不能链接
getOrElse
方法调用
最佳答案
签名getOrElse
对于 LeftProjection[A, B]
是:
def getOrElse[AA >: A](or: ⇒ AA): AA
即它期望参数是某种类型
AA
这是 A
的父类(super class)型.在第一个示例中,您省略了类型注释,允许编译器推断
Nothing
为 A
.然后,您提供了一个 LeftProjection[Nothing, Int]
类型的参数。 .因为
Nothing
是所有类型的子类型,LeftProjection[Nothing, Int]
微不足道的是一个父类(super class)型!类型系统中的这种特殊情况意味着它几乎是意外地进行了类型检查。然而,最具体的常见父类(super class)型
String
和 LeftProjection[String, Int]
是 Serializable
.所以,如果你想链接
Either
s,你需要一个可以接受另一个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
}
(您可以类似地编写
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
(或其某些父类(super class)型),您可以链接您的 Either
s。scala> Right[String, Int](2) leftOrElse Right[String, Int](4) leftOrElse Left[String, Int]("Error")
res1: Either[String,Int] = Left(Error)
关于Scala.Either getOrElse 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18366801/