【问题标题】:Release IO resources in scala without maintaining mutable state在不维护可变状态的情况下释放 Scala 中的 IO 资源
【发布时间】:2013-01-25 11:00:51
【问题描述】:

我需要使用一些 Java 库,它可能会在一个方法中抛出一些异常并在另一组方法中返回错误代码。到目前为止,它导致了像

这样的丑陋代码
val txn = mgr.prepareTransaction()
val accessRecord = txn.readByQuery(...)
var state : Either[MyError, Result] = null //
try {
  // do something here
  val result = txn.runCodeWithin(new Callable[Result]() {...})
  if (result == -1) {
    state = Left(CanNotReadRecord)
  } else {
    state = Right(txn.getCachedRecord())
  }
} catch {
  case e: Exception => state = Left(GeneralError(e))
} finally {
  state match {
    case Right(_) => txn.commit();
    case _        => txn.rollback();
  }
}

我最感兴趣的是摆脱 state 作为 var 和在 finally 块中检查状态的能力。请指教。

【问题讨论】:

  • 如果你有相同的模式,你可以将丑陋因素考虑到一个单一的实用方法中,该方法接受 3 个参数(mgr、readByQuery 的 arg 和一个为 runCodeWithin 创建可调用的块)。然后改用实用方法。它不会使这种特殊方法变得漂亮,但至少会减少它的足迹。
  • 这就是我实际在做的事情 - 将事务管理和游标提取到具有隐式错误生成器的实用程序方法中。但是它看起来仍然......很奇怪。

标签: scala immutability resource-management


【解决方案1】:

Scala 2.10 引入了Try 类,它是Either[Throwable, Result] 用例的功能更强大的替代品。它包含所有常见的 monad 操作(使理解起作用的东西)和一些其他有用的方法。 (check out the docs for Try here)

这是您的代码的可能重新实现,使用Try,并将CanNotReadRecord 替换为CanNotReadRecordException。它应该在功能上等同于您的示例,除了那个替换。

def txResults(txn: Transaction): Try[Record] = for {
    result <- Try{ txn.runCodeWithin(...) }
    checked <- result match {
        case -1 => Failure( new CanNotReadRecordException )
        case _ => Success( txn.getCachedRecord )
    }
} yield checked

txResults(txn) match {
    case Success(record) => txn.commit()
    case Failure(e) => txn.rollback() //and maybe handle `e`
}

【讨论】:

    【解决方案2】:

    Scala ARM(自动资源管理)库以一种完全密封的方式优雅地处理所有此类事情。

    检查一下。

    【讨论】:

    • 赞成,但我认为在这个特定示例中使用该库仍然很重要,因为取决于result,您有错误或记录,因此会产生Either[MyError, Result]。所以使用resource.either 会产生一个Either[Seq[Exception], Either[MyError, Result]],它必须合并到Either[MyError, Result]
    猜你喜欢
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多