gpt4 book ai didi

可选的 Kotlin 多平台支持

转载 作者:行者123 更新时间:2023-12-05 01:27:27 28 4
gpt4 key购买 nike

我正在使用现在转换为多平台 Kotlin 的 Java API。它曾经使用 java.lang.Optional 作为许多调用的返回类型。我明白这是 not the idiomatic Kotlin-way (参见 discussion )但这是一个现有的 API,Optional 保留(对于面向 Java 的客户端来说,这也不是一个的选择)。我的问题是如何

注意:代码只需要向外部APIreturn Optional.of(x)return Optional.empty()即可。任何内部使用都将被清除。

  • 我们如何使用 expect/actual/typealias在可用时使用真实 可选类?
  • 有没有办法避免在非 Java 目标上重新实现一个可选类(即惯用地使用 nullable? 后缀)

最佳答案

此时,Kotlin 不允许通过使用具有匹配 static声明。请关注此问题以获取更新: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?

这是一个错误:

Type alias expands to T?, which is not a class, an interface, or an object

所以你实际上需要一个非 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

关于可选的 Kotlin 多平台支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59006733/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com