在Kotlin尝试资源

时间:2014-11-17 09:48:24

标签: kotlin extension-methods try-with-resources

当我尝试在Kotlin中编写等效的Java try - 资源代码时,它对我不起作用。

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

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

但两者都不起作用。

有谁知道应该使用什么? 显然Kotlin语法doesn't have definition用于这样的构造,但也许我错过了一些东西。它定义了try块的语法,如下所示:

try : "try" block catchBlock* finallyBlock?;

5 个答案:

答案 0 :(得分:176)

kotlin stdlib(src)中有use - 函数。

如何使用它:

OutputStreamWriter(r.getOutputStream()).use {
    // by `it` value you can get your OutputStreamWriter
    it.write('a')
}

答案 1 :(得分:33)

TL; DR

没有特殊语法,但use功能

与Java相反,Kotlin没有特殊的语法。相反, try-with-resources 作为标准库函数use提供。

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的interface,它允许 try-with-resources 从Java SE7开始。 函数采用函数文字block,它在try中执行。与Java中的 try-with-resources 相同,Closeablefinally中获得关闭

同样在block内发生的失败会导致close执行,其中可能的例外是字面上的&#34;抑制&#34;只是忽略它们。 try-with-resources 不同,因为可以在Java的解决方案中请求此类例外。

如何使用

任何use类型都可以使用Closeable扩展名,即流,读者等。

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

大括号中的部分是block中的use(lambda在此处作为参数传递)。阻止完成后,您可以确定FileInputStream已关闭。

答案 2 :(得分:17)

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

对于其他不支持&#34;使用&#34;功能,我做了以下自制的资源尝试:

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)
    }
}

答案 3 :(得分:1)

我强烈建议对类使用 AutoCloseable。

<块引用>

AutoCloseable 对象在退出时自动调用 try-with-resources 块,对象已在 资源规范标头。

示例:

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

在主函数中:

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

输出:

> op1
close up.

答案 4 :(得分:0)

由于此StackOverflow帖子位于“ kotlin封闭示例”当前搜索结果的顶部附近,而其他任何答案(以及官方文档)都没有明确说明如何扩展Closeable(又名{{ 1}}),我想添加一个示例,说明如何制作自己的扩展java.io.Closeable的类。它是这样的:

Closeable

然后使用它:

import java.io.Closeable

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

在Kotlin游乐场here中查看此示例。