在 Kotlin 尝试资源

当我尝试在 Kotlin 编写一个类似于 Java try-with-resources语句的代码时,它并没有起作用。

我尝试了以下不同的变体:

try (writer = OutputStreamWriter(r.getOutputStream())) {
// ...
}

但这两种方法都不管用。有人知道应该用什么来代替吗?

显然科特林语法 不包括这样的构造,但也许我遗漏了一些东西。它将 try块的语法定义如下:

try : "try" block catchBlock* finallyBlock?;
40639 次浏览

Kotlin-stdlib (Src)中有一个 use函数。

使用方法:

OutputStreamWriter(r.getOutputStream()).use {
// `it` is your OutputStreamWriter
it.write('a')
}

编辑 : 以下响应对 Kotlin 1.0.x 仍然有效。对于 Kotlin 1.1,支持一个面向 Java 8的标准库,以支持可关闭资源模式。

对于其他不支持“ use”函数的类,我做了以下自制的“尝试使用资源”:

package info.macias.kotlin


inline fun <T:AutoCloseable,R> trywr(closeable: T, block: (T) -> R): R {
try {
return block(closeable);
} finally {
closeable.close()
}
}

然后你可以按照下面的方式使用它:

fun countEvents(sc: EventSearchCriteria?): Long {
return trywr(connection.prepareStatement("SELECT COUNT(*) FROM event")) {
var rs = it.executeQuery()
rs.next()
rs.getLong(1)
}
}

DR: 没有特殊的语法,只是一个函数

Kotlin 与 Java 不同,它没有特殊的语法来处理这个问题。相反,尝试使用资源是作为标准库函数 use提供的。

FileInputStream("filename").use { fis -> //or implicit `it`
//use stream here
}

use实现

@InlineOnly
public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
var closed = false
try {
return block(this)
} catch (e: Exception) {
closed = true
try {
this?.close()
} catch (closeException: Exception) {
}
throw e
} finally {
if (!closed) {
this?.close()
}
}
}

此函数被定义为所有 Closeable?类型的一般扩展。Closeable是 Java 的 接口,它允许 尝试使用资源与 JavaSE7一样。
函数的匿名函数是 block,在 try中执行。与 Java 中的 尝试使用资源相同,Closeablefinally中获得 关门了

此外,发生在 block内部的故障导致 close的执行,其中可能的异常通过忽略它们而被字面地“抑制”。这个不同于 尝试使用资源,因为在 爪哇咖啡的解决方案中可以请求这样的异常。

怎么用

use扩展可用于任何 Closeable类型,即流、读取器等。

FileInputStream("filename").use {
//use your stream by referring to `it` or explicitly give a name.
}

花括号中的部分就是 use中的 block(在这里传递一个 lambda 作为参数)。块完成后,可以确定 FileInputStream已关闭。

由于这篇 StackOverflow 文章位于当前搜索结果“ kotlin 可关闭示例”的顶部附近,而且没有其他答案(也没有官方文档)清楚地解释如何扩展 Closeable(又名 java.io.Closeable) ,我想我应该添加一个例子,说明如何创建自己的类来扩展 Closeable。是这样的:

import java.io.Closeable


class MyServer : Closeable {
override fun close() {
println("hello world")
}
}

然后使用它:

fun main() {
val s = MyServer()
s.use {
println("begin")
}
println("end")
}

看看 Kotlin Playground 的这个例子。

我将强烈推荐使用类自动关闭。

对象时自动调用 对象已在 资源规格说明标头。

例如:

class Resource : AutoCloseable {
fun op1() = println("op1")
override fun close() = println("close up.")
}

主要功能:

Resource().use {
it.op1()
}

产出:

> op1
close up.