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

New*_*bie 2 kotlin kotlin-native kotlin-multiplatform

Java中的Closeable接口提供了一种方便的抽象,可以方便地管理可关闭的资源。在多平台 kotlin 的背景下,是否有一种模式、实践或功能可以帮助打破共享/多平台 Closeable 接口和实际的 Java Closeable 接口之间的差距,因为它们必然是两种不同的类型?

无法关闭类型差异和/或具有标准库可关闭的影响是 Closeable 接口的激增,即使它们本质上是相同的东西,也无法跨库组合。

Jay*_*ard 6

Kotlin 团队已在 kotlinx-io 库中为您完成了此操作。

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

因为Closeable您应该直接使用该库,无需创建自己的库。


但如果您想创建自己的类似跨平台抽象,这将是一个很好的示例。这是它在幕后所做的事情......

通用实现实际上执行关闭逻辑,并且只期望每个平台都有可用的接口:(来源)

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)
Run Code Online (Sandbox Code Playgroud)

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

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
    }
}
Run Code Online (Sandbox Code Playgroud)

并且JS版本是新的界面:(来源)

actual interface Closeable {
    actual fun close()
}

@PublishedApi
internal actual fun Throwable.addSuppressedInternal(other: Throwable) {
}
Run Code Online (Sandbox Code Playgroud)

对于原生来说,它类似于 JS,对于每个平台等等......