如何使用 Kotlin Multiplatform 功能实现自定义平台逻辑?

How to implement custom platform logic using Kotlin Multiplatform feature?

Kotlin Multiplatform 是构建多平台应用程序的一个很好的特性,但目前(可能)仅限于 Kotlin Multiplatform 生态系统中的固有特性。我可以实现自定义构建逻辑来扩展 expectactual 等的解析策略吗?或者说将这些功能视为 多平台 的一般概念,但在构建过程中具有不同的行为。 Gradle 欢迎工作。

例如,如果相关的扩展点可用,可以编写一个 Kotlin 编译器插件来解析那些 expect/actual 端点,并可能将它们组合成实际平台特定的 运行时间逻辑,然后写一个Gradle插件来最终处理这些工件。

因此,如果有两个“多平台”场景都使用 jvm 作为“后端”,但提供不同的 api 具有与“前端”相同或相似的逻辑,则可以按照上述方式提供好处Kotlin Multiplatform 所做的 - 一次编写,运行 随处可见。

我更愿意称其为“api层多平台”,以区别 Kotlin Multiplatform 是“系统层多平台”。 “平台”可能更抽象。

这就是生产者所做的,就像 Kotlin Multiplatform 一样:

build.gradle.kts:

plugins {
    kotlin("jvm")
    id("<multiplatform-plugin-id>") // Comes with Kotlin compiler plugin too
}

dependencies {
    api("<common-dependency-notation>") // Another multiplatform library
}

common模块:

fun hello() {
    val logger = serviceLogger // Using api from that another multiplatform library
    logger.info("Hello")
}

expect fun hookOnStart(block: () -> Unit) // Needs to provide platform-specific implementations

platform模块:

actual fun hookOnStart(block: () -> Unit) { // Imaginary
    ClientEvents.START.register(block)
}

anotherPlatform 模块:

actual fun hookOnStart(block: () -> Unit) { // Imaginary
    val event = EventFactory.once(ClientStartEvent::class.java, block)
    GlobalEventHandler.register(event)
}

如前所述,构建后,每个平台都会有自己的工件,为 运行时间准备或作为库提供。他从另一个多平台库中受益,因为他可以通过共享代码为每个平台提供相同的功能。

以下是消费者的行为:(假设他在 platform

build.gradle.kts

plugins {
    kotlin("jvm")
}

dependencies {
    implementation("<previous-common-dependency-notation>") // From the previous author, mapped to `platform` version
}

业务逻辑:

fun runBussiness() {
    hello()
    hookOnStart { serviceLogger.info("world!") }
}

这是一个相当未知的领域,没有任何文件。

我会调查 kotlin-multiplatform gradle plugin 更多 in-depth 的源代码,看看您是否可以扩展现有的目标调色板和 expect/actual 行为。

我猜这个插件并不是真正为这种扩展而构建的,但如果你有充分的理由,你可能会提交功能请求并同时在本地分支上工作。

更新: 如果我正确理解了您的 use-case,您想要扩展 expect/actual 机制,该机制当前是基于 target/platform 的抽象? 我相信一种更通用的抽象方法,例如使用 interfaces,可以为您服务。但是,我可以看到您寻求的额外 compile-time 安全优势,但不确定 kotlin-multiplatform 插件需要进行哪些更改,以及 JetBrains 团队是否愿意朝这个方向发展。也许 Artyom Degtyarev 或 JetBrains 团队的某个人可以回答?