最后可以尝试Try吗?

时间:2017-06-09 14:53:24

标签: scala exception

我是Scala的新手,并查看了Try::apply

的源代码
def apply[T](r: => T): Try[T] =
  try Success(r) catch {
    case NonFatal(e) => Failure(e)
  }

它只是捕获非致命异常。但是,如果我需要最终条款怎么办?是否可以使用Try以功能方式模拟它?我的意思是

try{
   //acquire lock
   //do some
} finally {
  // release lock
}

Try{
   //acquire lock
   //do some
} 
//Now how to release?

2 个答案:

答案 0 :(得分:4)

由于UPDATE [Table Material Label] JOIN [IngredientsDB] on [Table Material Label.MaterialDescription] = [IngredientsDB.Item Number] SET [MaterialCode] = [Item Number] WHERE [MaterialDescription] = [Ingredient Name] 解析为某个值并且在某些内容失败时它不会展开堆栈,因此您可以在执行Try之后执行清理操作。例如:

Try

如果您愿意,可以使用自己的帮助程序将所有内容保存到单个表达式中:

val someLock = ??? // acquire some lock
val result = Try {
  // do something and return a result
}
someLock.release()

然后你可以写:

def withLock[A](f: Lock => A): Try[A] = {
  val lock = ??? // acquire the lock
  val res = f(lock)
  lock.release()
}

这通常被称为贷款模式

答案 1 :(得分:3)

类似的东西已经回答了here

TLTR; 使用Try monad没有标准的方法。

通常的解决方法是这样的:

def use[A <: { def close(): Unit }, B](resource: A)(code: A ⇒ B): B =
    try {
        code(resource)
    } finally {
        resource.close()
    }

您可以使用:

val path = Paths get "/etc/myfile"
use(Files.newInputStream(path)) { inputStream ⇒
    val firstByte = inputStream.read()
    ....
}

另一种解释为here的方法,暗示您通过添加额外的方法'withRelease'“扩展”标准'尝试'

implicit class TryOps[A <: { def close(): Unit }](res: Try[A]) {
  def withRelease() = res match {
    case Success(s) => res.close(); res
    case Failure(f) => res.close(); res
  }
}

然后,

Try {
   val inputStream = Files.newInputStream(path))
   ...
   inputStream
}.withRelease()