ZetCode

Kotlin actual 关键字

最后修改于 2025 年 4 月 19 日

Kotlin 多平台项目使用 actual 关键字为预期的声明提供特定于平台的实现。本教程将通过实际例子深入探讨 actual 关键字。

基本定义

actual 关键字是 Kotlin 多平台开发中 expect/actual 机制的一部分。一个 expect 声明指定了一个必须由特定于平台的 actual 声明实现的 API。

基本的 expect/actual 声明

最简单的用例包括在公共代码中声明一个预期的函数,并为每个平台提供实际的实现。这确保了跨平台的 API 一致性。

Common.kt
// Common module
expect fun platformName(): String
JvmMain.kt
// JVM platform
actual fun platformName(): String = "JVM"

在这个例子中,公共模块声明了一个预期的函数 platformName。JVM 平台提供了其实际实现。其他平台将需要它们自己的实际实现。

属性的 actual

actual 关键字也可以与属性一起使用。这允许对在公共代码中声明的属性进行特定于平台的实现。

Common.kt
// Common module
expect val platformVersion: String
NativeMain.kt
// Native platform
actual val platformVersion: String = "1.0.0-native"

这里,我们在公共代码中声明了一个预期的属性,并提供了一个特定于原生的实现。每个平台都需要提供它自己的这个属性的实际版本。

类的 actual

整个类可以用 expect 声明,并用 actual 实现。这对于共享接口或抽象类的特定于平台的实现很有用。

Common.kt
// Common module
expect class FileReader(path: String) {
    fun read(): String
    fun close()
}
JsMain.kt
// 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.kt
// Common module
expect fun getUUID(): String {
    // Default implementation for most platforms
    return java.util.UUID.randomUUID().toString()
}
NativeMain.kt
// Native platform
actual fun getUUID(): String {
    // Platform-specific implementation
    return generateNativeUUID()
}

在这里,大多数平台可以使用来自公共代码的默认实现,而原生平台提供其自己的专用版本。这减少了代码重复,同时允许平台定制。

类型别名的 actual

actual 关键字可以与类型别名一起使用,以提供特定于平台的类型映射。当底层类型跨平台不同时,这很有用。

Common.kt
// Common module
expect class PlatformDate
JvmMain.kt
// JVM platform
actual typealias PlatformDate = java.util.Date
JsMain.kt
// JavaScript platform
actual typealias PlatformDate = js("Date")

这种模式允许在共享代码中使用公共 PlatformDate 类型,同时映射到特定于平台的日期实现。每个平台都提供其自己的实际类型别名。

对象的 actual

单例对象也可以用 expect 声明,并用 actual 实现。这对于特定于平台的服务或管理器很有用。

Common.kt
// Common module
expect object PlatformTimer {
    fun schedule(delay: Long, task: () -> Unit)
}
AndroidMain.kt
// 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.kt
// Common module
expect enum class Platform {
    ANDROID, IOS, JVM, JS, NATIVE
}
CommonMain.kt
// Common actual implementation
actual enum class Platform {
    ANDROID, IOS, JVM, JS, NATIVE
}

虽然这个例子显示了一个公共的实际实现,但你可以根据需要提供特定于平台的版本,其中包含其他条目或行为。实际的枚举必须与 expect 声明的结构相匹配。

actual 声明的最佳实践

来源

Kotlin 多平台文档

本教程深入探讨了 Kotlin 的 actual 关键字,展示了它如何在多平台项目中实现特定于平台的实现。我们探讨了各种声明类型,包括函数、属性、类和对象。正确使用 expect/actual 声明有助于创建可维护的跨平台代码库。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有多年的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经写了超过 1400 篇文章和 8 本电子书。我有超过八年的编程教学经验。

列出 所有 Kotlin 教程