Kotlin 如何正确处理';使用';块
我想要一个Kotlin 如何正确处理';使用';块,kotlin,Kotlin,我想要一个可关闭的资源来自动关闭自己,但同时我希望能够处理任何可能的异常 考虑下面的代码 val opcPackage: OPCPackage URI.create(document.fileUrl).toURL().openStream().use { opcPackage = OPCPackage.open(it) // it = InputStream! } 在异常情况下,由于use块,InputStream将自动关闭。但是,执行流将被中断 我仍然希望处理此类异常,并对我的程
可关闭的
资源来自动关闭自己,但同时我希望能够处理任何可能的异常
考虑下面的代码
val opcPackage: OPCPackage
URI.create(document.fileUrl).toURL().openStream().use {
opcPackage = OPCPackage.open(it) // it = InputStream!
}
在异常情况下,由于use
块,InputStream将自动关闭。但是,执行流将被中断
我仍然希望处理此类异常,并对我的程序执行某些操作(例如,记录、发送信号ecc…)
以下内容未编译:
kotlin.runCatching {
URI.create(document.fileUrl).toURL().openStream().use {
opcPackage = OPCPackage.open(it)
}
}.onFailure {
// e.g. log and exit
}
这种方法违背了使用
的全部目的,因为我必须手动关闭可关闭的
URI.create(document.fileUrl).toURL().openStream().use {
try {
opcPackage = OPCPackage.open(it)
} catch (ex: Exception) {
// ...
it.close()
return internalServerError()
}
}
在这一点上,我不妨简单地使用
val inputStream = URI.create(document.fileUrl).toURL().openStream()
try {
opcPackage = OPCPackage.open(inputStream)
inputStream.close()
} catch (ex: Exception) {
inputStream.close()
return internalServerError()
}
但我正试图正确使用kotlin的功能
此用例的最佳代码段是什么?use()
允许您在一个表达式中处理资源管理,即使在出现异常的情况下也是如此。您仍然可以尝试捕捉它:
可能会过份。但它有很多优点。顺便说一句,请注意,使用val opcPackage=try{ create(document.fileUrl).toURL().openStream().use{ OPCPackage.open(it) } }捕获(e:SomeException){ //例如,记录并退出 //此处无需手动关闭 //您确实需要在此处中断控制流或提供默认OPCPackage }
的变量实际上也很好,您可能只需要将其用作表达式来初始化变量:runCatching
但是,即使捕获到内部异常,val opcPackageResult=runCatching{ create(document.fileUrl).toURL().openStream().use{ OPCPackage.open(it) } }.onFailure{ //例如,记录并退出 } //以后仍然需要处理结果类型
块的结尾仍将为您关闭资源:use()
或者您也可以使用普通的val opcPackage=URI.create(document.fileUrl.toURL().openStream().use{ 试一试{ OPCPackage.open(it) }捕获(例如:异常){ 返回internalServerError() } }
:try catch finally
谁说如果你在val inputStream=URI.create(document.fileUrl.toURL().openStream()) val opcPackage=try{ OPCPackage.open(inputStream) }捕获(例如:异常){ 返回internalServerError() }最后{ inputStream.close() }
会出现什么编译器错误?为什么使用中处理异常,你必须手动关闭资源?kotlin.runCatching
变量不能编译?你犯了什么错误?它应该可以编译。@AbhijitSarkar是的,很公平,几秒钟前它也击中了我。然而,即使删除手动关闭,代码似乎也不太正确。Joffrey下面的答案(第一个片段)看起来更合适。请提供关于封闭函数的更多信息,因为很难看到在这个表达式的中间使用变量突变和<代码>返回< /C> >语句。一种更为惯用的Kotlin方法是使用表达式来初始化变量,我想您的第一个代码片段就是我要找的。它结合了分配、资源自动关闭和异常处理,所有这些都在几行中。如果您真的想使用函数方法,我还添加了一个带有runCatching
的变体。但是,老实说,我看不出比try catch有什么大的改进:)@MarkoPacak而且,无论你选择什么,我都会亲自将这些表达式片段提取到现实生活中的函数中。在高级代码的中间留下这种低级别的处理通常很难看,但是您提取的内容取决于您想如何处理<代码>返回< /代码>。正如@ Joffrey所说的,使用一个经典的Test/Ccatch样式设计代码,一元函数/函数样式<代码> RuncatchrunCatching
不会返回runCatching
类型,它会返回一个OPCPackage
,其中包含一个Result
@LaksithaRanasingha good points。我修复了OPCPackage
示例,以避免对返回值的混淆。runCatching