为什么当我打字时一切正常?
Right(2).left getOrElse Right(4).left getOrElse Left("Error")
Run Code Online (Sandbox Code Playgroud)
但是当我键入此编译失败?
Right[String, Int](2).left getOrElse Right[String, Int](4).left getOrElse Left[String, Int]("Error")
Run Code Online (Sandbox Code Playgroud)
编译错误:
value getOrElse不是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
Run Code Online (Sandbox Code Playgroud)
即它期望参数是某种类型AA
的超类型A
.
在第一个例子,你离开了类型标注,让编译器来推断Nothing
的A
.然后,您提供了一个类型的参数LeftProjection[Nothing, Int]
.
因为Nothing
是所有类型的子类型,所以LeftProjection[Nothing, Int]
通常是超类型!类型系统中的这种特殊情况意味着它几乎是偶然地进行了类型检查.
然而,最具体的共同父类型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
}
Run Code Online (Sandbox Code Playgroud)
(您可以类似地编写rightOrElse
,这是一个更常见的用例.)
如果你使用implicits将它作为扩展方法,这在语法上会变得更有用.
implicit class EitherOps[A, B](e1: Either[A, B]) {
def leftOrElse(e2: => Either[A, B]): Either[A,B] = // as above
}
Run Code Online (Sandbox Code Playgroud)
因为这需要Either[A, B]
两个操作数,而不是A
或B
(或其某些超类型),你可以链接你的Either
s.
scala> Right[String, Int](2) leftOrElse Right[String, Int](4) leftOrElse Left[String, Int]("Error")
res1: Either[String,Int] = Left(Error)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2205 次 |
最近记录: |