【问题标题】:Getting Value of Either获得任何一个的价值
【发布时间】:2013-10-21 20:03:36
【问题描述】:

除了使用match之外,是否有类似Option的方式来getOrElseRightLeft值的实际内容?

scala> val x: Either[String,Int] = Right(5)
scala> val a: String = x match { 
                                case Right(x) => x.toString
                                case Left(x) => "left" 
                       }
a: String = 5

【问题讨论】:

    标签: scala either


    【解决方案1】:

    Nicolas Rinaudo 关于在leftright 投影上调用getOrElse 的答案可能最接近Option.getOrElse

    或者,您也可以fold

    scala> val x: Either[String,Int] = Right(5)
    x: Either[String,Int] = Right(5)
    
    scala> val a: String = x.fold(l => "left", r => r.toString)
    a: String = 5
    

    由于上述折叠中没有使用l,您也可以写成x.fold(_ => "left", r => r.toString)

    编辑: 实际上,您可以通过在 leftright 投影上调用 toOption 来获得 Option.getOrElse,例如,

    scala> val o: Option[Int] = x.right.toOption
    o: Option[Int] = Some(5)
    
    scala> val a: String = o.map(_.toString).getOrElse("left")
    a: String = 5
    

    【讨论】:

      【解决方案2】:

      我不是特别喜欢Either,因此我对它不是很熟悉,但我相信您正在寻找预测:either.left.getOrElseeither.right.getOrElse

      请注意,投影也可以用于理解。这是直接来自文档的示例:

      def interactWithDB(x: Query): Either[Exception, Result] =
        try {
          Right(getResultFromDatabase(x))
        } catch {
          case ex => Left(ex)
        }
      
      // this will only be executed if interactWithDB returns a Right
      val report =
        for (r <- interactWithDB(someQuery).right) yield generateReport(r)
      if (report.isRight)
        send(report)
      else
        log("report not generated, reason was " + report.left.get)
      

      【讨论】:

      • 你为什么不喜欢Either
      • @Kevin 这只是我个人的意见,但我发现在两种情况下它很有用:返回失败或成功,或者返回两种可能结果之一。使用Try 可以更好地服务前者,而后者似乎只是草率的编程——我觉得如果我的方法可以返回StringDate,例如,它可以做一些重构。
      • 我认为在验证框架中返回成功或失败很有用。然后,公共 API 会明确地告诉您它可以返回哪种成功/失败,即使它们是自定义的有状态类,同时避免尴尬地使用检查异常。我目前正在研究的一个例子是一个事件源框架,它将基于一些验证来调度一个事件。它可能是预期的事件类型,也可能是某种“无效事件”
      • 试一试,如果您有错误但并非异常的行为怎么办?这仍然是 Try 的好人选吗?也许它可能是例外,但我尝试编写没有必要例外的代码。
      • @Nicolas Rinaudo,@Nicolas Rinaudo,如果你想告诉客户端函数可能返回几种类型的错误,例如 InvalidDataError 和 InetrnalError,你会如何使用 Try?使用 Either,您可以这样写: def method(input: Int):Either[(Option[InvalidDataError], Option[InternalError]), Int] - 该方法的客户端现在知道可能发生什么样的错误,并处理它们如果他想。您将如何使用 Try 做到这一点?
      【解决方案3】:

      给定两边的类型A,即Either[A, A],我们可以使用Either.merge

      ...从 Either 实例中提取值,无论它们是否 左或右。

      请注意,如果左右类型不同,则结果是这两种类型中的最小上限,在最坏的情况下可能会变成Any

      val e: Either[Int, String] = Right("hello")
      e.merge // hello: Any
      

      【讨论】:

        【解决方案4】:

        在 Scala 2.12 中,有一个 getOrElse 方法可以获取“右”值,但您不能直接将它用于“左”值。但是,您可以这样做:e.swap.getOrElse(42)

        【讨论】:

        • 我不认为将 'any' 作为一种类型是值得的。感觉就像你打破了类型系统
        • @StanislavSobolev 你是什么意思?不应丢失类型信息。交换 Either 只会给你一个新的 Either 交换类型。
        猜你喜欢
        • 2019-12-11
        • 2018-03-19
        • 1970-01-01
        • 1970-01-01
        • 2013-11-10
        • 2013-08-06
        • 1970-01-01
        • 2014-11-26
        • 1970-01-01
        相关资源
        最近更新 更多