scala 简化Try.recover

fiei3ece  于 4个月前  发布在  Scala
关注(0)|答案(1)|浏览(58)

我在Scala中经常看到的一个模式是“Try unwrapping”,通常看起来像这样:

Try {
  input.charAt(100)    // Some error-prone calculation
} match {
  case Success(c) => c // just unwrap the value
  case Failure(e) =>
    println(e)         // log the exception
    '?'                // and provide a default value
}

字符串
这段代码很好,但我对case Success(c) => c有点困扰,它基本上只是一个恒等转换(也称为噪声)。转换的灵魂是错误Map函数,它记录异常并提供默认值,这就是我想带到前台的东西。
我可以看到两个替代方案,摆脱身份转换:
我们可以使用recover方法:

Try {
  input.charAt(100)    // Some error-prone calculation
} recover { e =>
    println(e)         // log the exception
    '?'                // and provide a default value
} get


但是recover产生了一个Try[T](它保证是一个Success)。这必须用一个悬空的get(在这种风格下也需要postFixOps)来展开。
我们也可以使用getOrElse,但这不允许我们记录异常。

Try {
  "input".charAt(100) // Some error-prone calculation
} getOrElse { 
  // println(e)       // We don't have access to the exception and can't log it
  'a'                 // provide a default value.
}


我真正想要的是一个unwraprecover++方法,如

def unwrap[U >: T](pf: PartialFunction[Throwable, U]): U


要么从成功中打开T,要么从失败中打开Throwable,并将其转换为具有部分功能的U。
我能看到的最简单的方法是将recover/get管道 Package 在我添加到Try的扩展方法中,但这听起来也有点矫枉过正。
有没有人有一个巧妙的方法来实现这种行为?
P.S.我发现了这个相关的问题,表明倾向于模式匹配,但我想看看在过去的5年里是否有更好的东西出现-Try recover get vs Try match

nnvyjq4y

nnvyjq4y1#

我已经使用了recover模式来捕获和记录错误。你也可以从recover块中重新抛出异常(或不同的异常),就像下面这个简单的JSON解析代码:

Try {
  (parse(json) \ "something").extractOrElse("default")
}.recover({
  case exception: Exception => throw new IllegalArgumentException(s"Invalid JSON: ${exception.getMessage}")
}).get

字符串

相关问题