Kotlin Multiplatform 中,如何使用 ‘expect‘ 和 ‘actual‘ 来处理不同平台的 API 调用

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

KMP使用expectactual 关键字

在 Kotlin Multiplatform 项目中,expectactual 关键字被用于处理不同平台的 API 调用。以下是如何使用这些关键字的详细步骤和规则:

1、 定义预期声明(Expected Declarations)
在共通代码集中(例如 commonMain),使用 expect 关键字声明一个结构,这可以是函数、属性、类、接口、枚举或注解。这些预期声明不包含实现代码,而是作为平台无关的 API 供共通代码使用。

2、 提供实际声明(Actual Declarations)
在每个平台特定的源代码集中(例如 androidMainiosMain),声明与预期声明相同的结构,并使用 actual 关键字标记。这些实际声明通常包含使用特定平台库的实现。

3、 编译器匹配
编译特定目标平台时,编译器会尝试匹配共通代码集中的每个 expect 声明与平台特定源代码集中的相应 actual 声明。编译器确保:

  • 每个 expect 声明在每个平台特定源代码集中都有匹配的 actual 声明。
  • expect 声明不包含实现。
  • 每个 actual 声明与对应的 expect 声明使用相同的包名。

4、 使用依赖注入(Dependency Injection, DI)
在采用 DI 框架的项目中,可以在共通代码中使用 expect 声明接口,然后通过 DI 框架配置,为不同平台注入 actual 实现。这种方式适用于管理平台特定的依赖。

5、 处理枚举类
当使用 expect 关键字声明枚举类时,每个平台模块应该提供一个 actual 声明,包含相同的枚举值常数,也可以包含额外的枚举值常数。这允许在共通代码中声明枚举,而在平台特定代码中扩展它。

6、 类型别名
如果需要使用特定平台的现有类型实现预期声明,可以使用类型别名(typealias)来连接预期声明和平台特定的类型。这在无法直接向平台类型添加 actual 关键字时非常有用。

7、 扩展可见性
实际实现的可见度可以超过对应的预期声明。这在不希望将 API 公开给所有用户时非常有用。从 Kotlin 2.0 开始,编译器不再限制可见性的变化。

通过这种方式,Kotlin Multiplatform 允许开发者编写可在多个平台上运行的共享代码,同时保留对每个平台特定 API 的访问能力,实现代码的最大化重用和原生性能的结合。

代码示例

以下是一个使用 expectactual 关键字在 Kotlin Multiplatform 项目中处理不同平台 API 调用的代码示例:

共通代码 (commonMain):

// 预期声明:在共通代码中声明一个函数,但不提供实现。
expect fun getPlatformName(): String
expect class PlatformSpecificClass {
    fun doSomething(): String
}

Android 平台代码 (androidMain):

// 实际声明:为 Android 平台提供 getPlatformName() 函数的具体实现。
actual fun getPlatformName(): String = "Android"

// 实际声明:为 Android 平台提供 PlatformSpecificClass 类的具体实现。
actual class PlatformSpecificClass actual constructor() {
    actual fun doSomething(): String = "Doing something on Android"
}

iOS 平台代码 (iosMain):

// 实际声明:为 iOS 平台提供 getPlatformName() 函数的具体实现。
actual fun getPlatformName(): String = "iOS"

// 实际声明:为 iOS 平台提供 PlatformSpecificClass 类的具体实现。
actual class PlatformSpecificClass actual constructor() {
    actual fun doSomething(): String = "Doing something on iOS"
}

在这个示例中,我们定义了两个预期声明:一个函数 getPlatformName() 和一个类 PlatformSpecificClass。这些预期声明在共通代码中声明,但它们的实现被留给了特定平台的代码。

对于每个平台,我们提供了相应的实际声明。例如,getPlatformName() 函数在 Android 上返回字符串 “Android”,而在 iOS 上返回 “iOS”。同样,PlatformSpecificClass 类在两个平台上有不同的实现,但它们都有一个 doSomething() 方法,该方法返回一个特定于平台的字符串。

这样,当您在共通代码中调用 getPlatformName() 或创建 PlatformSpecificClass 的实例时,Kotlin 编译器会自动选择并使用适当平台的实际实现。这使得您可以在不同的平台上重用共通逻辑,同时保持对平台特定功能的访问。


欢迎关注我的公众号AntDream查看更多精彩文章!

AntDream

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值