expect 和 actual 机制
1. 概念与作用
expect 和 actual 是 Kotlin 多平台开发(KMP)中的核心机制,用于实现平台特定代码的声明与实现分离:
expect:在公共模块中声明一个预期(平台无关)的 API。actual:在各平台模块中提供该 API 的具体实现。
2. 基本语法
公共模块(Common)
// 声明一个预期函数
expect fun getPlatformName(): String
平台模块(如 JVM)
// 提供实际实现
actual fun getPlatformName(): String = "JVM"
3. 使用场景
| 场景 | 示例 |
|---|---|
| 平台特定 API 调用 | 文件操作、网络请求 |
| 第三方库适配 | Android 的 SharedPreferences |
| 性能优化 | 使用平台原生数据结构 |
4. 规则与限制
- 必须成对出现:每个
expect声明必须有对应的actual实现。 - 可见性一致:
actual实现的可见性不能低于expect声明。 - 类型兼容:实际返回类型必须是预期类型的子类型。
5. 高级用法
多平台类实现
// Common
expect class PlatformTimer {
fun start()
fun stop()
}
// JVM
actual class PlatformTimer actual constructor() {
actual fun start() { /* JVM 实现 */ }
actual fun stop() { /* JVM 实现 */ }
}
默认实现(iOS 常见)
// Common
expect val isDebug: Boolean
// iOS (可提供默认值)
actual val isDebug: Boolean = false
6. 实际项目中的应用
- 数据库驱动:在公共模块定义
expect class DatabaseDriver,在 Android 使用 Room,在 iOS 使用 SQLite。 - UI 组件:声明通用 UI 行为,各平台用原生组件实现。
- 依赖注入:公共模块定义服务接口,平台模块提供具体实例。
7. 常见问题解决方案
问题1:缺少 actual 实现
✅ 检查所有目标平台是否都有对应实现
问题2:类型不匹配
✅ 使用泛型或接口抽象降低平台差异
问题3:测试困难
✅ 为公共模块编写通用测试,平台模块补充集成测试
最佳实践:尽量将业务逻辑放在公共模块,仅将真正平台相关的代码通过
expect/actual隔离。
