首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala.Either getOrElse方法

Scala.Either getOrElse方法
EN

Stack Overflow用户
提问于 2013-08-21 20:13:33
回答 1查看 3.7K关注 0票数 7

为什么我打字的时候一切都很好?

代码语言:javascript
复制
Right(2).left getOrElse Right(4).left getOrElse Left("Error")

但是当我输入这个编译失败了?

代码语言:javascript
复制
Right[String, Int](2).left getOrElse Right[String, Int](4).left getOrElse Left[String, Int]("Error")

编译错误:

值getOrElse不是java.io.Serializable的成员 ( RightString,Int.left getOrElse RightString,Int.left getOrElse LeftString,Int)

所以我不能链接getOrElse方法调用

EN

回答 1

Stack Overflow用户

发布于 2013-08-21 20:31:35

getOrElseLeftProjection[A, B]的签名是:

代码语言:javascript
复制
def getOrElse[AA >: A](or: ⇒ AA): AA

也就是说,它期望参数是某种类型的AA,它是A的超级类型。

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

因为Nothing是所有类型的一个子类型,所以LeftProjection[Nothing, Int]基本上是一个超级类型!这种特殊情况在类型系统中意味着它的类型检查几乎是偶然的.

然而,StringLeftProjection[String, Int]最常见的超级类型是Serializable

因此,如果您想要链接Either,您需要一个可以接受另一个Either[A, B] (而不仅仅是AB )的方法。

您似乎需要的方法如下所示:

代码语言:javascript
复制
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,这是一个更常见的用例。)

如果将其作为一种扩展方法,使用becomes,这在语法上就变得更有用了。

代码语言:javascript
复制
implicit class EitherOps[A, B](e1: Either[A, B]) {
  def leftOrElse(e2: => Either[A, B]): Either[A,B] = // as above
}

因为这需要两个操作数的Either[A, B],而不是AB (或其中的某些超级类型),所以可以链接Either

代码语言:javascript
复制
scala> Right[String, Int](2) leftOrElse Right[String, Int](4) leftOrElse Left[String, Int]("Error")
res1: Either[String,Int] = Left(Error)
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18366801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档