如何在Scala中进行for-understandingnce中最好地处理带有副作用的函数?
我有一个理解,通过调用函数f1创建一种资源(x)开始.这个资源有一个close -method需要在结束时调用,但是如果for-comprehension以某种方式失败(除非.
所以我们有类似的东西:
import scala.util.{Try,Success,Failure}
trait Resource {
def close() : Unit
}
// Opens some resource and returns it as Success or returns Failure
def f1 : Try[Resource] = ...
def f2 : Try[Resource] = ...
val res = for {
x <- f1
y <- f2
} yield {
(x,y)
}
Run Code Online (Sandbox Code Playgroud)
我应该在哪里调用close方法?我可以在for-comprehension结束时将其称为最后一个语句(z < - x.close),在yield-part中,或在for-comprehension之后(res._1.close).它们都不能确保在发生错误时调用close(例如,如果f2失败).或者,我可以分开
x <- f1
Run Code Online (Sandbox Code Playgroud)
出于这样的理解:
val res = f1
res match {
case Success(x) => {
for {
y <- f2
}
x.close
}
case Failure(e) => ...
:
Run Code Online (Sandbox Code Playgroud)
这将确保调用close但代码不是很好.难道没有更聪明,更干净的方法来实现同样的目标吗?
当我遇到这样的问题时,我决定两种可能性:
在大多数情况下,我更喜欢自己实现以避免额外的依赖 这是贷款模式的代码:
def using[A](r : Resource)(f : Resource => A) : A =
try {
f(r)
} finally {
r.close()
}
Run Code Online (Sandbox Code Playgroud)
用法:
using(getResource())(r =>
useResource(r)
)
Run Code Online (Sandbox Code Playgroud)
由于您需要2个资源,因此需要使用此模式两次:
using(getResource1())(r1 =>
using(getResource2())(r2 =>
doYourWork(r1, r2)))
Run Code Online (Sandbox Code Playgroud)
您还可以查看以下答案:
| 归档时间: |
|
| 查看次数: |
905 次 |
| 最近记录: |