【问题标题】:Either to Try and vice versa in Scala在 Scala 中尝试,反之亦然
【发布时间】:2019-05-14 12:44:50
【问题描述】:

Scala 标准库中是否有从EitherTry 的任何转换?也许我遗漏了一些东西,但我没有找到它们。

【问题讨论】:

    标签: scala


    【解决方案1】:

    据我所知,这在标准库中不存在。尽管Either 通常与Left 失败和Right 成功一起使用,但它实际上旨在支持两种可能的返回类型的概念,其中一种不一定是失败情况。我猜这些人们期望存在的转换并不存在,因为Either 并没有真正设计为像Try 这样的成功/失败单子。话虽如此,自己丰富Either 并添加这些转换非常容易。这可能看起来像这样:

    object MyExtensions {
      implicit class RichEither[L <: Throwable,R](e:Either[L,R]){
        def toTry:Try[R] = e.fold(Failure(_), Success(_))
      }
    
      implicit class RichTry[T](t:Try[T]){
        def toEither:Either[Throwable,T] = t.transform(s => Success(Right(s)), f => Success(Left(f))).get
      }  
    }
    
    object ExtensionsExample extends App{
      import MyExtensions._
    
      val t:Try[String] = Success("foo")
      println(t.toEither)
      val t2:Try[String] = Failure(new RuntimeException("bar"))
      println(t2.toEither)
    
      val e:Either[Throwable,String] = Right("foo")
      println(e.toTry)
      val e2:Either[Throwable,String] = Left(new RuntimeException("bar"))
      println(e2.toTry)
    }
    

    【讨论】:

    • 虽然这是一个很好的解决方案,但截至 2018 年,toTrytoEither 已包含在 scala 2.12 中。可能值得在您回答的顶部添加一个编辑。
    【解决方案2】:
    import scala.util.{ Either, Failure, Left, Right, Success, Try }
    
    implicit def eitherToTry[A <: Exception, B](either: Either[A, B]): Try[B] = {
      either match {
        case Right(obj) => Success(obj)
        case Left(err) => Failure(err)
    
      }
    }
    implicit def tryToEither[A](obj: Try[A]): Either[Throwable, A] = {
      obj match {
        case Success(something) => Right(something)
        case Failure(err) => Left(err)
      }
    }
    

    【讨论】:

    • 你为什么要抛出错误并用Try 捕获它而不是用Failure 包装?
    • +1 与 other answer 相比,代码和模式匹配更清晰。
    【解决方案3】:

    【讨论】:

    【解决方案4】:

    答案取决于如何将Failure 转换为Left(反之亦然)。如果您不需要使用异常的详细信息,则可以通过Option 的中间路线将Try 转换为Either

    val tried = Try(1 / 0)
    val either = tried.toOption.toRight("arithmetic error")
    

    另一种方式的转换需要你构造一些 Throwable。可以这样做:

    either.fold(left => Failure(new Exception(left)), right => Success(right))
    

    【讨论】:

      猜你喜欢
      • 2014-05-28
      • 2012-09-29
      • 1970-01-01
      • 2013-08-10
      • 2014-11-08
      • 2012-02-16
      • 2013-08-16
      • 2012-06-27
      • 2017-02-05
      相关资源
      最近更新 更多