提问人:hippietrail 提问时间:5/4/2023 更新时间:5/5/2023 访问量:312
在 Kotlin Multiplatform 中,我可以有一个“expect”类型,在一个平台上是简单类型,在另一个平台上是参数化类型吗?
In Kotlin Multiplatform can I have an 'expect' type that is a simple type on one platform and a parameterized type on another?
问:
从概念上讲,我想这样做:
// Expect file (commonMain)
expect class PlatformDir
// Platform-specific implementation for JVM
actual typealias PlatformDir = File
// Platform-specific implementation for Linux/macOS
actual typealias PlatformDir = CPointer<DIR>
接受简单的 JVM 类型,但不接受 Linux/macOS 的参数化类型:
预期类“PlatformDir”在模块中没有实际声明 对于本机,以下声明是 不兼容,因为类型参数的数量不同: public 实际类型别名 PlatformDir = CPointer
实际类型别名右侧的类型参数应为 其类型参数按相同顺序排列,例如 'actual typealias Foo<A, B> = Bar<A, B>'
实际类型别名“PlatformDir”没有相应的预期值 declaration 以下声明不兼容,因为 number 的类型参数不同: public final expect 类 PlatformDir
首先将参数化类型移动到其自己的 typealias 中也不起作用:
private typealias CPointer_DIR = CPointer<DIR>
actual typealias PlatformDir = CPointer_DIR
它仍然抱怨类型参数的数量错误,并有这个额外的错误:
实际类型别名的右侧应该是一个类,而不是其他类型别名
我是 Kotlin 和 JVM 以及 Kotlin Multiplatform 的菜鸟,所以我觉得这一定是可能的,而无需将两者都包装在一个类中。 谷歌搜索我找不到任何人讨论这个问题,AI 聊天机器人似乎只是抓住了越来越复杂并且也没有构建的稻草。
答:
您正在尝试对 JVM 使用简单类型,对本机平台使用参数化类型,但不幸的是,Kotlin 不支持在预期和实际声明中使用不同数量的类型参数。
但是,您可以通过稍微不同的方法实现所需的结果,在期望声明中使用泛型类,然后提供实际实现。下面是一个示例:
// Expect file (commonMain)
expect class PlatformDir<T>
// Platform-specific implementation for JVM
actual typealias PlatformDir<T> = File
// Platform-specific implementation for Linux/macOS
actual typealias PlatformDir<T> = CPointer<DIR>
在本例中,你在 expect 声明中使用泛型类,然后为每个平台提供实际实现。对于 JVM,实际上并未使用类型参数 T,而对于本机平台,则按预期使用。
请记住,这种方法可能会有些令人困惑,因为在 JVM 实现中,类型参数 T 并不是真正必需的。这更像是一种解决方法,以保持不同平台之间的兼容性。
评论
Expected class 'PlatformDir' has no actual declaration in module multiplatform-test.jvmMain for JVM The following declaration is incompatible because number of type parameters is different: public actual typealias PlatformDir<T> = File defined in root package in file jvmMain.kt
Type arguments in the right-hand side of actual type alias should be its type parameters in the same order, e.g. 'actual typealias Foo<A, B> = Bar<A, B>'
评论