此时,Kotlin 不允许通过使用具有匹配 static 声明的 Java 类来为具有 companion object 的预期类提供 actual typealias。关注此问题以获取更新:KT-29882。
目前,您可以通过在预期的 Optional 类之外单独声明工厂函数来解决此问题,如下所示:
expect class Optional<T : Any> {
fun get(): T
fun isPresent(): Boolean
/* ... */
}
expect object Optionals {
fun <T : Any> of(t: T): Optional<T>
fun empty(): Optional<Nothing>
}
不一定是object,你可以使用顶级函数。
然后,在 JVM 上,您必须为 Optional 类提供 actual typealias,此外,还需要为 Optionals 对象提供简单的实际实现:
actual typealias Optional<T> = java.util.Optional<T>
actual object Optionals {
actual fun <T : Any> of(t: T): Optional<T> = java.util.Optional.of(t)
actual fun empty(): Optional<Nothing> = java.util.Optional.empty()
}
至于不为非 JVM 平台提供实现,我怀疑这是可能的,因为这需要将 Optional 用法的一些非平凡的编译时转换为可空类型。所以你会想要这样的东西:
actual typealias Optional<T> = T?
现在是一个错误:
类型别名扩展为T?,它不是类、接口或对象
所以你实际上需要一个非 JVM 实现。为避免对每个非 JVM 目标重复它,您可以声明一个自定义源集并将其与特定于平台的源集链接,以便它们从那里获得实现:
build.gradle.kts
kotlin {
/* targets declarations omitted */
sourceSets {
/* ... */
val nonJvmOptional by creating {
dependsOn(getByName("commonMain"))
}
configure(listOf(js(), linuxX64())) { // these are my two non-JVM targets
compilations["main"].defaultSourceSet.dependsOn(nonJvmOptional)
}
}
}
然后,在这个自定义源集内(例如在 src/nonJvmOptional/kotlin/OptionalImpl.kt 中),您可以为非 JVM 目标提供实际实现。
这是 Github 上的一个最小项目示例,我在其中进行了上述实验:h0tk3y/mpp-optional-demo