[英]“return” and “try-catch-finally” block evaluation in scala
[英]analogous Try block to try/finally block in scala
scala 的类似方式是什么Try
:
timer.start()
try {
doThis()
} finally {
timer.cancel()
}
鉴于Try
中的异常只是创建了一个Failure
值(与使用try
时将控制权转移到外部 catch 块相反),原始finally
块中的代码只需要在Try
之后执行。 换句话说,这将:
timer.start()
val result = Try{
doThis()
}
timer.cancel()
result
据我所知,没有内置的快捷方式可以避免捕获result
以原样返回。
由于Try
不会在您的程序流程中引发异常,我相信只需编写以下内容:
timer.start()
Try(doThis())
timer.cancel()
如果您希望处理异常(而不是盲目地忽略它)或调用结果,您可以将Try(doThis())
分配给一个值并进一步处理它。
怎么样
Try {
scala.util.control.Exception.ultimately {
timer.cancel()
} {
doThis()
}
}
?
尽管其他答案另有说明,但正确的答案是Try
不能完全类似于传统的try...finally
。 这样做的原因是Try
将忽略某些类型的异常,包括InterruptedException
、 ControlThrowable
等。
考虑是否按照其他答案的建议使用Try
:
lock.lock()
val t = Try(doStuff()) // Doesn't absorb all types of exceptions!
lock.unlock() // THIS MIGHT BE SKIPPED!!!
t.get
如果线程在doStuff()
期间被中断,则会抛出InterruptedException
,并且Try
将重新抛出它而不是创建Failure
! 这将导致lock.unlock()
被跳过(你可能会死锁)。 如果doStuff()
调用一个调用非本地返回的 lambda(它抛出ControlThrowable
的子类型),也会发生同样的情况。
这可能是标准 Scala 库在Try
类中不包含finally
方法的原因——因为它不能正常工作。
不过,也有一些好消息。 Scala 2.13 引入了Using ,它本质上执行了一个 try-with-resources。 我们可以欺骗它做一个更一般的尝试......最后通过使用一个虚拟资源:
Using(lock.lock())(_ => doStuff())(_ => lock.unlock())
如果您在try
之前没有任何惯用的操作,那么您可以在第一个参数列表中提供一个Unit
:
Using(())(_ => doStuff())(_ => lock.unlock())
但无论如何, Try
不会完成这项工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.