当前位置:嗨网首页>书籍在线阅读

10-特定平台声明

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

2.3.3 特定平台声明

Kotlin多平台项目的一个关键功能是通用代码依赖于特定平台的声明方式。在其他语言中,可以通过在通用代码中构建一组接口,并在平台特定的模块中实现这些接口来实现。然而,对于Kotlin这种跨平台项目来说,这种方法并不理想。为了达到多平台代码复用的目的,Kotlin提供了一种预期和实际的声明机制。通过这种机制,通用模块可以定义一个预期的声明,然后在平台模块根据提供的预期声明来实现实际声明。

具体使用时,可以通过expected以及actual方式来声明通用代码与平台特定部分的依赖关系,其中,expected用于声明一个指定的API(类、接口、注释、顶层声明等),actual用于声明与API相关的平台实现或是用于实现在外部库中对API的现有别名引用。下面是官方提供的一个关于多平台项目实现的例子。

//通用模块
expect class Foo(bar: String) {
    fun frob()
}
fun main(args: Array<String>) {
    Foo("Hello").frob()
}

相应的JVM平台模块的实现如下。

//JVM特定模块
actual class Foo actual constructor(val bar: String) {
    actual fun frob() {
        println("Frobbing the $bar")
    }
}

学习Kotlin的多平台特性时应注意以下几点。

  • 通用模块中的预期声明及其平台实现使用完全相同的限定名称。
  • 预期声明使用expect关键字标记,实际声明使用actual关键字标记。
  • 预期声明不包含任何实现代码。

预期声明不仅限于接口和接口成员,还可以使用expect修饰符修饰其他声明,包括顶级声明和注释等。如果有一个特定平台库,现在希望在通用代码中使用这个库并为另一个平台提供自己的实现,则可以使用typealias来修饰实际声明。代码示例如下。

expect class AtomicRef<V>(value: V) {
  fun get(): V
  fun set(value: V)
  fun getAndSet(value: V): V
  fun compareAndSet(expect: V, update: V): Boolean
}
actual typealias AtomicRef<V> = java.util.concurrent.atomic.AtomicReference<V>

如果需要为项目编写测试程序,以便在每个平台项目中进行编译和运行,可以使用Kotlin提供的测试库。其中,kotlin-test-annotations-common库作用于通用模块,kotlin-test-junit库作用于JVM模块,kotlin-test-js库则作用于JavaScript模块。