我正在研究一个支持JVM,iOS和macOS的Kotlin / Native Multiplatform项目。我的设置包含以下模块:
- common
- ios
- jvm
- macos
我想使用一些本机代码作为actual
类,并将expected
类放入common
中。但是,对于多个目标(iOS和macOS),实际的类实现是相同的。有没有一种方法可以设置我的资源(也许在Gradle中),这样我就不必维护实际类的两个相同副本了?
答案 0 :(得分:3)
Stately具有相当复杂的配置。 iOS和Macos共享所有相同的代码。
要构建项目,需要commonMain
,nativeCommonMain
依赖于此,实际上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
}
该结构可能比您需要的要深,但是对于Linux和Windows,我们需要一些不同的东西。我认为,Egor的上述答案更容易理解。
我们实际上在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
}
actual typealias AtomicInt = AtomicInteger
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)
}
答案 1 :(得分:2)
在Okio中,我们声明了两个附加的源集nativeMain
和nativeTest
,并配置了内置的本地源集来依赖它们:
apply plugin: 'org.jetbrains.kotlin.multiplatform'
kotlin {
iosX64()
iosArm64()
linuxX64()
macosX64()
mingwX64('winX64')
sourceSets {
nativeMain {
dependsOn commonMain
}
nativeTest {
dependsOn commonTest
}
configure([iosX64Main, iosArm64Main, linuxX64Main, macosX64Main, winX64Main]) {
dependsOn nativeMain
}
configure([iosX64Test, iosArm64Test, linuxX64Test, macosX64Test, winX64Test]) {
dependsOn nativeTest
}
}
}
答案 2 :(得分:0)
如果所有三个实现都是相同的,只需将代码放在common
中。 expect/actual
仅用于在不同平台上不同的事物