尝试使用资源:“使用” Kotlin中的扩展功能并不总是有效 [英] try-with-resources: "use" extension function in Kotlin does not always work

查看:123
本文介绍了尝试使用资源:“使用” Kotlin中的扩展功能并不总是有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在表达Java的尝试用资源在Kotlin构建。根据我的理解,作为 AutoClosable 实例的每个表达式都应该提供使用扩展函数。

I had some trouble expressing the Java's try-with-resources construct in Kotlin. In my understanding, every expression that is an instance of AutoClosable should provide the use extension function.

这是一个完整的例子:

import java.io.BufferedReader;
import java.io.FileReader;

import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;

public class Test {

    static String foo(String path) throws Throwable {
        try (BufferedReader r =
           new BufferedReader(new FileReader(path))) {
          return "";
        }
    }

    static String bar(TupleQuery query) throws Throwable {
        try (TupleQueryResult r = query.evaluate()) {
          return "";
        }
    }
}

Java-to-Kotlin转换器创建此输出:

The Java-to-Kotlin converter creates this output:

import java.io.BufferedReader
import java.io.FileReader

import org.openrdf.query.TupleQuery
import org.openrdf.query.TupleQueryResult

object Test {

    @Throws(Throwable::class)
    internal fun foo(path: String): String {
        BufferedReader(FileReader(path)).use { r -> return "" }
    }

    @Throws(Throwable::class)
    internal fun bar(query: TupleQuery): String {
        query.evaluate().use { r -> return "" } // ERROR
    }
}

foo 工作正常,但 bar 中的代码无法编译:

foo works fine, but the code in bar does not compile:

Error:(16, 26) Kotlin: Unresolved reference.
None of the following candidates is applicable
because of receiver type mismatch: 
public inline fun <T : java.io.Closeable, R>
???.use(block: (???) -> ???): ??? defined in kotlin.io

query.evaluate()来自芝麻并实现 AutoClosable 。它是Kotlin错误,还是有原因导致它不起作用?

query.evaluate() is from Sesame and implements AutoClosable. Is it a Kotlin bug, or is there a reason why it does not work?

我使用的是IDEA 15.0.3使用Kotlin 1.0.0-beta-4584-IJ143-12以及以下 sasame-runtime 版本:

I am using IDEA 15.0.3 with Kotlin 1.0.0-beta-4584-IJ143-12 and the following sasame-runtime version:

<groupId>org.openrdf.sesame</groupId>
<artifactId>sesame-runtime</artifactId>
<version>4.0.2</version>


推荐答案

Kotlin目前针对Java 6,因此其标准库不使用 AutoCloseable 接口。 使用函数仅支持Java 6 Closeable 接口。请参阅问题跟踪器以供参考。

Kotlin targets Java 6 at the moment, so its standard library does not use the AutoCloseable interface. The use function only supports the Java 6 Closeable interface. See the issue tracker for reference.

您可以在项目中创建使用函数的副本,并修改它以使用 AutoCloseable替换 Closeable

You can create a copy of the use function in your project and modify it to replace Closeable with AutoCloseable:

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

这篇关于尝试使用资源:“使用” Kotlin中的扩展功能并不总是有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆