Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 如何正确处理';使用';块_Kotlin - Fatal编程技术网

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
会出现什么编译器错误?为什么
runCatching
变量不能编译?你犯了什么错误?它应该可以编译。@AbhijitSarkar是的,很公平,几秒钟前它也击中了我。然而,即使删除手动关闭,代码似乎也不太正确。Joffrey下面的答案(第一个片段)看起来更合适。请提供关于封闭函数的更多信息,因为很难看到在这个表达式的中间使用变量突变和<代码>返回< /C> >语句。一种更为惯用的Kotlin方法是使用表达式来初始化变量,我想您的第一个代码片段就是我要找的。它结合了分配、资源自动关闭和异常处理,所有这些都在几行中。如果您真的想使用函数方法,我还添加了一个带有
runCatching
的变体。但是,老实说,我看不出比try catch有什么大的改进:)@MarkoPacak而且,无论你选择什么,我都会亲自将这些表达式片段提取到现实生活中的函数中。在高级代码的中间留下这种低级别的处理通常很难看,但是您提取的内容取决于您想如何处理<代码>返回< /代码>。正如@ Joffrey所说的,使用一个经典的Test/Ccatch样式设计代码,一元函数/函数样式<代码> Runcatch
可能会过份。但它有很多优点。顺便说一句,请注意,
runCatching
不会返回
OPCPackage
类型,它会返回一个
Result
,其中包含一个
OPCPackage
@LaksithaRanasingha good points。我修复了
runCatching
示例,以避免对返回值的混淆。