gpt4 book ai didi

scala - 如何确保资源在 Scala 中的理解中关闭

转载 作者:行者123 更新时间:2023-12-04 22:29:48 27 4
gpt4 key购买 nike

如何在 Scala 的 for-comprehensions 中最好地处理带有副作用的函数?

我有一个理解,首先通过调用函数 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)
}

我应该在哪里调用 close 方法?我可以在 for-comprehension 的末尾调用它作为最后一个语句 (z <- x.close),在 yield-part 中,或在 for-comprehension (res._1.close) 之后。如果发生错误(例如,如果 f2 失败),它们都不能确保 close 被调用。
或者,我可以分开
x <- f1 

出于这样的理解:
val res = f1
res match {
case Success(x) => {
for {
y <- f2
}
x.close
}

case Failure(e) => ...
:

这将确保调用 close 但不是很好的代码。
没有更聪明、更干净的方法来实现同样的目标吗?

最佳答案

当我遇到这样的问题时,我会在两种可能性之间做出决定:

  • 使用 Scala ARM
  • 自己实现 Loan Pattern(链接不稳定,可能会死)

  • 在大多数情况下,我更喜欢自己的实现以避免额外的依赖。
    这是贷款模式的代码:
    def using[A](r : Resource)(f : Resource => A) : A =
    try {
    f(r)
    } finally {
    r.close()
    }

    用法:
    using(getResource())(r =>
    useResource(r)
    )

    由于您需要 2 个资源,因此您需要两次使用此模式:
    using(getResource1())(r1 =>
    using(getResource2())(r2 =>
    doYourWork(r1, r2)))

    您还可以查看以下答案:
  • Scala: Disposable Resource Pattern
  • functional try & catch w/ Scala
  • Using a variable in finally block
  • 关于scala - 如何确保资源在 Scala 中的理解中关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32351063/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com