Есть ли возможность или шаблон Kotlin-Multiplatform, которые могут помочь реализовать общую абстракцию, скажем, для интерфейса Closeable? - PullRequest
0 голосов
/ 18 ноября 2018

Интерфейс Closeable в Java предоставляет удобную абстракцию, которая облегчает управление ресурсами, которые могут быть закрыты. В контексте многоплатформенного kotlin, есть ли шаблон, практика или функция, которая может помочь преодолеть разрыв между разделяемым / многоплатформенным интерфейсом Closeable и фактическим интерфейсом Java Closeable, зная, что это обязательно два разных типа?

Результатом невозможности закрыть разницу типов и / или наличия закрываемой стандартной библиотеки является распространение интерфейсов Closeable, которые нельзя объединить между библиотеками, даже если они в основном одно и то же.

1 Ответ

0 голосов
/ 18 ноября 2018

Это уже сделано для вас в библиотеке kotlinx-io от команды Kotlin.

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 представляет собой простой псевдоним типа, который соответствует ожидаемому интерфейсу, что означает его совместимость с существующим кодом и реализацию подавления внутреннего исключения. (источник)

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 представляет собой новый интерфейс: (источник)

actual interface Closeable {
    actual fun close()
}

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

Для native это похоже на JS , и так далее для каждой платформы ...

...