我是新手Scala
并查看了源代码Try::apply
def apply[T](r: => T): Try[T] =
try Success(r) catch {
case NonFatal(e) => Failure(e)
}
Run Code Online (Sandbox Code Playgroud)
它只是捕获非致命异常。但是如果我需要 finally 子句怎么办?是否可以以Try
功能方式模拟它?我的意思是像
try{
//acquire lock
//do some
} finally {
// release lock
}
Run Code Online (Sandbox Code Playgroud)
和
Try{
//acquire lock
//do some
}
//Now how to release?
Run Code Online (Sandbox Code Playgroud)
TLTR; Try monad 没有标准方法可以做到这一点。
通常的解决方法是这样的:
def use[A <: { def close(): Unit }, B](resource: A)(code: A ? B): B =
try {
code(resource)
} finally {
resource.close()
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用:
val path = Paths get "/etc/myfile"
use(Files.newInputStream(path)) { inputStream ?
val firstByte = inputStream.read()
....
}
Run Code Online (Sandbox Code Playgroud)
此处解释的另一种方法意味着您通过添加附加方法“withRelease”来“扩展”标准“Try”
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
}
}
Run Code Online (Sandbox Code Playgroud)
然后,
Try {
val inputStream = Files.newInputStream(path))
...
inputStream
}.withRelease()
Run Code Online (Sandbox Code Playgroud)
由于Try
解析为一个值并且当出现故障时它不会展开堆栈,因此您可以简单地在Try
执行后执行清理操作。例如:
val someLock = ??? // acquire some lock
val result = Try {
// do something and return a result
}
someLock.release()
Run Code Online (Sandbox Code Playgroud)
如果您愿意,您可以推出自己的助手,将所有内容保存在一个表达式中:
def withLock[A](f: Lock => A): Try[A] = {
val lock = ??? // acquire the lock
val res = f(lock)
lock.release()
}
Run Code Online (Sandbox Code Playgroud)
然后你可以写:
val res = withLock { lock =>
// some operation
}
Run Code Online (Sandbox Code Playgroud)
这通常称为贷款模式。
归档时间: |
|
查看次数: |
2069 次 |
最近记录: |