前言
Kotlin的expect关键字一般用在多平台上,比如在多平台项目中的common中声明方法签名,然后由不同的平台去实现该方法,从而实现一个多平台(跨平台)方法.
创建KMM项目可以参考: KMM(二)+Compose(二) 开发一个Kotlin多平台应用_滔lt的博客-CSDN博客
正文
接下来就说一下Kotlin expect的几种声明方式
1.顶层函数和顶层扩展函数
在commonMain文件夹中声明:
在androidMain(和其他平台)文件夹中实现:
声明并实现后,不管是共享代码还是平台代码中都可以使用相应方法
2.属性
声明:
expect val isDebug: Boolean
实现:
actual val isDebug: Boolean = BuildConfig.DEBUG
3.注解
声明:
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
internal expect annotation class ExpectAnnotation()
实现:
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
internal actual annotation class ExpectAnnotation()
4.枚举
声明:
expect enum class Enum
实现:
actual enum class Enum {
enum1,
enum2,
enum3,
}
5.接口
声明:
expect interface Interface {
fun fun1()
fun fun2(): String
}
实现:
actual interface Interface {
actual fun fun1()
actual fun fun2(): String
fun fun3() {
"fun3".loge()
}
}
6.类
声明:
expect class Class() {
fun fun1()
fun fun2(): String
}
实现:
actual class Class {
actual fun fun1() {
}
actual fun fun2(): String {
return getUUID()
}
}
经测试,sealed class可以,data class好像用不了
ps:在公共模块使用接口和类暂时需要手动导包
7.typealias
使用kotlin的typealias特性,我们可以将一个已经实现类映射为expect的实现
我们接下来实现一个多平台的ViewModel
先去common目录下的build.gradle.kts文件中
添加viewmodel的依赖:
val androidMain by getting {
dependencies {
api("androidx.appcompat:appcompat:1.2.0")
api("androidx.core:core-ktx:1.3.1")
api("androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1")//增加vm依赖
}
}
声明:
expect open class MViewModel() {
protected open fun onCleared()
}
androidMain实现(直接使用ViewModel):
import androidx.lifecycle.ViewModel
open class MyViewModel : ViewModel() {
override fun onCleared() {
super.onCleared()
}
}
actual typealias MViewModel = MyViewModel
ps:这里说一下为什么要实现一下ViewModel才使用 typealias,首先ViewModel是个抽象类,但又没必要搞成抽象的,最重要的是Kotlin的protected和Java的protected可见性不同,所以导致typealias无法直接匹配上,不知道Kotlin后续要怎么补上这个坑,参考下图和文章:
desktopMain实现:
actual open class MViewModel {
protected actual open fun onCleared() {
}
}
上面代码放在了Github的expects目录: ltttttttttttt/KMM_and_Compose_Sample
参考Kotlin官网: Connect to platform-specific APIs | Kotlin
如有错误欢迎大佬们指出
end