【问题标题】:How to flatten a Try[Option[T]]如何展平 Try[Option[T]]
【发布时间】:2013-11-26 13:48:08
【问题描述】:

我想将Try[Option[T]] 扁平化为Try[T]

这是我的代码

def flattenTry[T](t: Try[Option[T]]) : Try[T] = {
  t match {
    case f : Failure[T] => f.asInstanceOf[Failure[T]]
    case Success(e) => 
      e match {
        case None => Failure[T](new Exception("Parsing error"))
        case Some(s) => Success(s)
      }
  }
}

有没有更好的办法?

【问题讨论】:

    标签: scala scala-option


    【解决方案1】:

    你可以试试这样更整洁的东西:

    val t = Try(Some(1))
    val tt = t.flatMap{
      case Some(i) => Success(i) 
      case None => Failure(new Exception("parsing error"))
    }
    

    更一般地说,这将是:

    def flattenTry[T](t: Try[Option[T]]) : Try[T] = {
      t.flatMap{
        case Some(s) => Success(s) 
        case None => Failure(new Exception("parsing error"))
      }    
    }
    

    诀窍是将Option 转换为Try 以使用平面地图。

    【讨论】:

      【解决方案2】:

      使用getOrElse,你也可以这样写:

      def flattenTry[T](t: Try[Option[T]]): Try[T] = {
        t flatMap { o => o map (Success(_)) getOrElse Failure(new Exception("parsing error")) }
      }
      

      您可以将其缩短,但可能会牺牲功能纯度(投掷是一种副作用)和性能(由于投掷/接球):

      def flattenTry[T](t: Try[Option[T]]): Try[T] = {
        Try(t.get getOrElse { throw new Exception("parsing error") })
      }
      

      【讨论】:

        【解决方案3】:

        一种可能的方法是使用Try(o.get)o: Option 转换为o: Try

        这非常简洁,但是在处理None 时会抛出和捕获异常,这有时可能是性能问题(或有时是意识形态/代码规则问题)。不过,代码非常简洁易读,我认为值得一提:

        def flattenTry[T](t: Try[Option[T]]) : Try[T] = {
          t.flatMap(o => Try(o.get))
        }
        

        注意:不是我推荐使用它,而是为了完整性:甚至更短的版本也是可能的,即使Try 失败,它也会抛出/捕获:

        def flattenTry[T](t: Try[Option[T]]) : Try[T] = {
          Try(t.get.get)
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-08-10
          • 1970-01-01
          • 2018-09-10
          • 1970-01-01
          • 2019-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多