Scala.Either getOrElse 方法

标签 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")

编译错误:

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)型.

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

因为 Nothing是所有类型的子类型,LeftProjection[Nothing, Int]微不足道的是一个父类(super class)型!类型系统中的这种特殊情况意味着它几乎是意外地进行了类型检查。

然而,最具体的常见父类(super class)型StringLeftProjection[String, Int]Serializable .

所以,如果你想链接 Either s,你需要一个可以接受另一个Either[A, B]的方法,而不仅仅是 AB .

您似乎想要的方法如下所示:
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]对于两个操作数,而不是 AB (或其某些父类(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/

相关文章:

scala - reduceBykey Spark 维护秩序

scala - 将 List[Either[A, B]] 平铺到 List[B],就像 List[Option[B]] 平铺到 List[B]

scala - 如何在Either中累积错误?

scala - Scala Future 的优雅处理[任一]]

scala - Spark 字数统计示例 : why error: value split is not a member of Char at the REPL?

scala - Playframework异常的CPU负载

scala - 嵌入式 scala 与嵌入式 groovy

scala - 如何在 try catch block 中初始化 val 对象?

scala - 在 Scala 中结合 Futures (Twitter) 和两者

Scala:将整个列表的 Either 与每个元素的 Either 结合起来