KMM Kotlin expect的几种声明方式

前言

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后续要怎么补上这个坑,参考下图和文章:

学习Kotlin(三)类和接口_滔lt的博客-CSDN博客

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

对Kotlin或KMP感兴趣的同学可以进Q群 101786950

如果这篇文章对您有帮助的话

可以扫码请我喝瓶饮料或咖啡(如果对什么比较感兴趣可以在备注里写出来)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值