Scala.getOrElse方法之一
为什么我打字的时候一切都很好Scala.getOrElse方法之一,scala,either,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(Right
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
方法调用对于LeftProjection[a,B]
的getOrElse
的签名是:
def getOrElse[AA >: A](or: ⇒ AA): AA
i、 e.它期望参数是某种类型的AA
,它是a
的超类型
在第一个示例中,您省略了类型注释,允许编译器为A
推断Nothing
。然后,您提供了一个类型为LeftProjection[Nothing,Int]
的参数
因为Nothing
是所有类型的子类型,LeftProjection[Nothing,Int]
只是一个超类型!类型系统中的这种特殊情况意味着它几乎是偶然进行类型检查的
但是,String
和LeftProjection[String,Int]
最具体的常见超类型是Serializable
因此,如果你想链接
或者s,你需要一种方法,它可以采用另一种或者[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
}
因为这要求两个操作数都使用或[A,B]
,而不是A
或B
(或其某些超类型),所以您可以将或s链接起来
scala> Right[String, Int](2) leftOrElse Right[String, Int](4) leftOrElse Left[String, Int]("Error")
res1: Either[String,Int] = Left(Error)
这看起来是一种非常模糊的方法,可以获得相当直接的直通行为。为什么不干脆换一种方式写,而不是把你想要的行为强加给那些方法呢?