是否有更惯用的方法在Scala中打开资源并将方法应用于此方法(直接从java翻译):
var is: FileInputStream = null
try {
is = new FileInputStream(in)
func(is)
} catch {
case e: IOException =>
println("Error: could not open file.")
println(" -> " + e)
exit(1)
} finally {
if(is) is.close()
}
答案 0 :(得分:19)
贷款模式以各种方式在github上的Josh Suereth的scala-arm库中实现。
然后您可以使用这样的资源:
val result = managed(new FileInputStream(in)).map(func(_)).opt
将返回包含在func
中的Option
的结果,并负责关闭输入流。
要在创建资源时处理可能的异常,您可以与scala.util.control.Exception
对象结合使用:
import resource._
import util.control.Exception.allCatch
allCatch either {
managed(new FileInputStream(in)).map(func(_)).opt
} match {
case Left(exception) => println(exception)
case Right(Some(result)) => println(result)
case _ =>
}
答案 1 :(得分:13)
答案 2 :(得分:5)
这可能是一个不希望功能化的情况。已经提到的贷款模式只是错误处理的比较版本的封装,但这与函数式编程无关,并且还负责处理错误。
如果你真的想要它的功能,可以使用error handling monad来实现。出于好的理由,我提供的链接是Haskell特定的文档,因为Scala不支持这种“硬核”功能实践。
我会建议您采取必要的方式并最终使用try catch ...您还可以通过错误处理扩展贷款模式但这意味着如果您想要在某些方面处理错误,则必须编写特殊功能情况或你必须传递一个部分函数进行错误处理(这只是你已经在代码中的catch块中获得的东西)。
答案 3 :(得分:0)
从Scala 2.13
开始,标准库提供了专用的资源管理实用程序:Using
。
在这种情况下,它可以与FileInputStream
一起使用,因为它实现了AutoCloseable
以便与输入文件一起播放,并且无论如何,之后都要关闭文件资源:
import scala.util.{Using, Failure}
import java.io.FileInputStream
Using(new FileInputStream(in)) {
is => func(is)
}.recoverWith {
case e: java.io.IOException =>
println("Error: could not open file.")
Failure(e)
}
由于Using
产生了Try
,提供了操作结果或错误,因此我们可以通过Try#recoverWith
处理异常。