Kotlin Multiplatform:共享多个目标(iOS、macOS)的实际类实现

ssc*_*lli 4 intellij-idea kotlin kotlin-native kotlin-multiplatform

我正在开发一个支持 JVM、iOS 和 macOS 的 Kotlin/Native 多平台项目。我的设置有以下模块:

- common
- ios
- jvm
- macos
Run Code Online (Sandbox Code Playgroud)

我想使用一些本机代码作为actual类并将一个expected类放入common. 但是,对于多个目标(iOS 和 macOS),实际的类实现是相同的。有没有办法可以设置我的源代码(也许在 Gradle 中),这样我就不必维护实际类的 2 个相同副本?

Kev*_*gan 5

Stately 有一个相当复杂的配置。iOS 和 Macos 共享所有相同的代码。

为了构建该项目,有commonMainnativeCommonMain取决于 ,而实际上appleMain取决于nativeCommonMain

commonMain {
    dependencies {
        implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
    }
}

jvmMain {
    dependsOn commonMain
    dependencies {
        implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
    }
}

nativeCommonMain {
    dependsOn commonMain
}

appleMain {
    dependsOn nativeCommonMain
}

configure([iosX64Main, iosArm64Main, macosMain, iosArm32Main]) {
    dependsOn appleMain
}

Run Code Online (Sandbox Code Playgroud)

该结构可能比您需要的更深,但我们需要针对 Linux 和 Windows 的不同的东西。我认为叶戈尔上面的答案更容易理解。

我们实际上在 Stately 中定义了多平台原子,因此您可以使用它们作为灵感,或者实际上只使用库本身。

https://github.com/touchlab/Stately

常见的

expect class AtomicInt(initialValue: Int) {
  fun get(): Int
  fun set(newValue: Int)
  fun incrementAndGet(): Int
  fun decrementAndGet(): Int

  fun addAndGet(delta: Int): Int
  fun compareAndSet(expected: Int, new: Int): Boolean
}
Run Code Online (Sandbox Code Playgroud)

虚拟机

actual typealias AtomicInt = AtomicInteger
Run Code Online (Sandbox Code Playgroud)

本国的

actual class AtomicInt actual constructor(initialValue:Int){
  private val atom = AtomicInt(initialValue)

  actual fun get(): Int = atom.value

  actual fun set(newValue: Int) {
    atom.value = newValue
  }

  actual fun incrementAndGet(): Int = atom.addAndGet(1)

  actual fun decrementAndGet(): Int = atom.addAndGet(-1)

  actual fun addAndGet(delta: Int): Int = atom.addAndGet(delta)

  actual fun compareAndSet(expected: Int, new: Int): Boolean = atom.compareAndSet(expected, new)

}
Run Code Online (Sandbox Code Playgroud)