目前,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>
}
这不一定需要是一个对象
,你可以只使用顶级函数。
然后,在JVM上,您需要为Optional
类提供一个实际的类型别名
,并且另外还要提供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 {
sourceSets {
val nonJvmOptional by creating {
dependsOn(getByName("commonMain"))
}
configure(listOf(js(), linuxX64())) {
compilations["main"].defaultSourceSet.dependsOn(nonJvmOptional)
}
}
}
然后,在这个自定义的源集合中(例如在src/nonJvmOptional/kotlin/OptionalImpl.kt
中)您可以为非JVM目标提供实际的实现。
以下是我在Github上进行上述实验的最小项目示例:h0tk3y/mpp-optional-demo
actual typealias Optional<T> = T?
能够正常工作,那就太棒了。 - drekbour