Kotlin actual 关键字
最后修改于 2025 年 4 月 19 日
Kotlin 多平台项目使用 actual 关键字为预期的声明提供特定于平台的实现。本教程将通过实际例子深入探讨 actual 关键字。
基本定义
actual 关键字是 Kotlin 多平台开发中 expect/actual 机制的一部分。一个 expect 声明指定了一个必须由特定于平台的 actual 声明实现的 API。
基本的 expect/actual 声明
最简单的用例包括在公共代码中声明一个预期的函数,并为每个平台提供实际的实现。这确保了跨平台的 API 一致性。
// Common module expect fun platformName(): String
// JVM platform actual fun platformName(): String = "JVM"
在这个例子中,公共模块声明了一个预期的函数 platformName。JVM 平台提供了其实际实现。其他平台将需要它们自己的实际实现。
属性的 actual
actual 关键字也可以与属性一起使用。这允许对在公共代码中声明的属性进行特定于平台的实现。
// Common module expect val platformVersion: String
// Native platform actual val platformVersion: String = "1.0.0-native"
这里,我们在公共代码中声明了一个预期的属性,并提供了一个特定于原生的实现。每个平台都需要提供它自己的这个属性的实际版本。
类的 actual
整个类可以用 expect 声明,并用 actual 实现。这对于共享接口或抽象类的特定于平台的实现很有用。
// Common module
expect class FileReader(path: String) {
fun read(): String
fun close()
}
// JavaScript platform
actual class FileReader actual constructor(path: String) {
actual fun read(): String {
// JS-specific implementation
return "JS file content"
}
actual fun close() {
// JS-specific cleanup
}
}
这个例子展示了一个在公共代码中声明的与平台无关的文件读取器接口,以及一个特定于 JavaScript 的实现。actual 关键字标记了实现的所有部分。
带有默认实现的 actual
在某些情况下,你可能希望在公共代码中提供一个默认实现,该实现可以在需要时被特定于平台的实际实现覆盖。
// Common module
expect fun getUUID(): String {
// Default implementation for most platforms
return java.util.UUID.randomUUID().toString()
}
// Native platform
actual fun getUUID(): String {
// Platform-specific implementation
return generateNativeUUID()
}
在这里,大多数平台可以使用来自公共代码的默认实现,而原生平台提供其自己的专用版本。这减少了代码重复,同时允许平台定制。
类型别名的 actual
actual 关键字可以与类型别名一起使用,以提供特定于平台的类型映射。当底层类型跨平台不同时,这很有用。
// Common module expect class PlatformDate
// JVM platform actual typealias PlatformDate = java.util.Date
// JavaScript platform
actual typealias PlatformDate = js("Date")
这种模式允许在共享代码中使用公共 PlatformDate 类型,同时映射到特定于平台的日期实现。每个平台都提供其自己的实际类型别名。
对象的 actual
单例对象也可以用 expect 声明,并用 actual 实现。这对于特定于平台的服务或管理器很有用。
// Common module
expect object PlatformTimer {
fun schedule(delay: Long, task: () -> Unit)
}
// Android platform
actual object PlatformTimer {
actual fun schedule(delay: Long, task: () -> Unit) {
android.os.Handler().postDelayed(task, delay)
}
}
这里,我们声明了一个跨平台的计时器 API,并提供了一个特定于 Android 的实现。每个平台都将实现其自己的计时器功能版本,同时保持一致的 API。
枚举的 actual
枚举可以用 expect 声明,并用 actual 实现,以允许特定于平台的枚举条目或行为。
// Common module
expect enum class Platform {
ANDROID, IOS, JVM, JS, NATIVE
}
// Common actual implementation
actual enum class Platform {
ANDROID, IOS, JVM, JS, NATIVE
}
虽然这个例子显示了一个公共的实际实现,但你可以根据需要提供特定于平台的版本,其中包含其他条目或行为。实际的枚举必须与 expect 声明的结构相匹配。
actual 声明的最佳实践
- 完全匹配签名: Actual 声明必须在名称、参数和返回类型方面与其 expect 对应项完全匹配。
- 记录平台差异: 清楚地记录实际实现中任何特定于平台的行为或限制。
- 尽量减少特定于平台代码: 尽可能多地将逻辑保留在公共代码中,仅使用 actual 处理必要的平台特定内容。
- 测试每个平台: 确保测试所有实际实现,因为它们的行为可能有所不同。
- 使用有意义的名称: 选择清晰的名称来指示实际实现的平台特定性质。
来源
本教程深入探讨了 Kotlin 的 actual 关键字,展示了它如何在多平台项目中实现特定于平台的实现。我们探讨了各种声明类型,包括函数、属性、类和对象。正确使用 expect/actual 声明有助于创建可维护的跨平台代码库。
作者
列出 所有 Kotlin 教程。