是否有Kotlin-Multiplatform功能或模式可以帮助实现Closeable接口的通用抽象?

时间:2018-11-17 21:49:19

标签: kotlin kotlin-native kotlin-multiplatform

Java中的Closeable接口提供了一种方便的抽象,它简化了可关闭资源的管理。在多平台Kotlin中,是否存在一种模式,实践或功能可以在知道共享/多平台Closeable接口和实际Java Closeable接口之间必然存在两种不同类型的情况下帮助它们之间的鸿沟?

无法关闭类型差异和/或具有标准库可关闭性的结果是,即使在本质上是同一件事上,也无法跨库组合的Closeable接口激增。

1 个答案:

答案 0 :(得分:2)

这已经在Kotlin团队的kotlinx-io库中为您完成了。

https://github.com/Kotlin/kotlinx-io

对于Closeable,您应该直接使用该库,而无需创建自己的库。


但是,如果您想创建自己的类似跨平台抽象,则可以作为一个很好的示例。这是它在幕后做的...

常见实现,实际上执行关闭逻辑,只是希望每个平台都具有可用的接口:(source)

expect interface Closeable {
    fun close()
}

inline fun <C : Closeable, R> C.use(block: (C) -> R): R {
    try {
        val result = block(this)
        close()
        return result
    } catch (first: Throwable) {
        try {
            close()
        } catch (second: Throwable) {
            first.addSuppressedInternal(second)
        }
        throw first
    }
}

@PublishedApi
internal expect fun Throwable.addSuppressedInternal(other: Throwable)

JVM版本只是一个简单的类型别名,它与预期的接口相匹配,这意味着它与现有代码兼容,并且实现了抑制内部异常的实现。 (source)

actual typealias Closeable = java.io.Closeable

@PublishedApi
internal actual fun Throwable.addSuppressedInternal(other: Throwable) {
    AddSuppressedMethod?.invoke(this, other)
}

private val AddSuppressedMethod: Method? by lazy {
    try {
        Throwable::class.java.getMethod("addSuppressed", Throwable::class.java)
    } catch (t: Throwable) {
        null
    }
}

JS版本是一个新界面:(source)

actual interface Closeable {
    actual fun close()
}

@PublishedApi
internal actual fun Throwable.addSuppressedInternal(other: Throwable) {
}

对于native it is similar to JS,对于每个平台,依此类推...