我在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.
}
型
我真正想要的是一个unwrap
或recover++
方法,如
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
1条答案
按热度按时间nnvyjq4y1#
我已经使用了recover模式来捕获和记录错误。你也可以从recover块中重新抛出异常(或不同的异常),就像下面这个简单的JSON解析代码:
字符串