Kotlin/Native v0.9 来啦!

1,226 阅读3分钟
原文链接: www.kotliner.cn

Kotlin Native v0.9 发布啦,不要看到数字就觉得这只是一个普通的版本,实际上,它是一次编译工具链、Gradle 插件、IDE 插件等等重大版本更新。

其中这版最重要的更点内容如下:

  • 编译器和标准库迁移到 Kotlin 1.3-M2
  • 标准库支持无符号类型
  • 对 C/Objective-C/Swift 兼容也支持无符号类型
  • 支持协程的稳定版本
  • 修订并发支持
  • 引入kotlin.native

支持 Kotlin 1.3-M2

为了迎接即将发布的 Kotlin 1.3,Kotlin/Native v0.9 的编译器和标准库已经迁移到了 Kotlin 1.3-M2上。所有新版本引入的特性和功能(包括内联类、无符号类型等等)我们都可以在 Kotlin/Native 当中体验到。

支持无符号类型

Kotlin 从 1.3 开始所有的后端都支持无符号类型,包括 JVM、Native 和 JS。例如下面的代码:

fun main(args: Array<String>) {
    println(maxOf(1u, UInt.MAX_VALUE))
}

在所有的平台上都可以正常运行,并输出 4294967295。 标准库当中很多主流的运算也都已经支持了无符号类型。

无符号类型与平台类型的兼容和映射

我们不仅在 Kotlin 内部支持无符号类型,在于平台语言兼容时,还会将这些类型映射成合适的 C、Objective-C 和 Swift 类型。例如,我们可以看一下下面的网络代码示例,其中演示了如何将数据从 socket 当中读到 Kotlin 的ByteArray当中 :

buffer.usePinned { pinned ->
    while (true) {
        val length = recv(commFd, pinned.addressOf(0), buffer.size.convert(), 0).toInt()
        .ensureUnixCallResult("read") { it >= 0 }
        if (length == 0) break
        send(commFd, pinned.addressOf(0), length.convert(), 0)
            .ensureUnixCallResult("send") { it >= 0 }
    }
}

需要指出的是,我们可以看到有些地方明显存在潜在不安全的有符号和无符号类型转换的可能(这些地方调用了内部的convert()函数)。POSIX API
ssize_t recv(int socket, void *buffer, size_t length, int flags);
则可以正确的映射成 Kotlin 签名如下:

typealias ssize_t = Long
typealias size_t = ULong
...
fun recv(arg0: Int, arg1: CValuesRef<*>?, arg2: size_t, arg3: Int): ssize_t

稳定的协程支持

考虑到协程在 Kotlin 1.3 中会结束实验状态,我们在 Kotlin/Native v0.9 中支持新的协程 API。 包kotlin.coroutines.experimental 当中的实验状态的协程 API 不再支持。

修订并发支持

Kotlin/Native v0.8 中引入了单例对象的冻结(freeze),这样允许我们创建一个线程安全的全局对象来共享状态。v0.9 当中我们仔细的重做了所有的并发逻辑,并将它们移入了kotlin.native.concurrent当中。重要的更新点包括:

  • 重做AtomicInt, AtomicLong, AtomicNativePtrAtomicReference
  • lazy代理支持冻结的对象

  • 新增DetachedObjectGraph类,用于封装游离的对象。

例如:

dispatch_async_f(asyncQueue, DetachedObjectGraph {
    Data(clock_gettime_nsec_np(CLOCK_REALTIME))
}.asCPointer(), staticCFunction {
    it ->
    initRuntimeIfNeeded()
    val data = DetachedObjectGraph<Data>(it).attach()
    println("in async: $data")
})

在 macOS 上,可变对象 Data 的控制权可以转移给另一个异步队列。

另一个重要的方面,之前全局变量是 thread-local 的,现在它们除非被 @SharedImmutable 或者 @ThreadLocal 标注,否则只允许主线程访问,其他线程访问它们时会抛出运行时异常;如果被 @SharedImmutable 标注,那么这个全局变量会在初始化完成之后冻结,如果被 @ThreadLocal 标准,那么每个线程都会持有一份自己的副本,详细请参见: Kotlin/Native 的并发 – 全局变量和单例

kotlin.native

为了让标准库有一个更好的结构以便于跨平台项目的开发,所有的原包 konan 的内容都移到 kotlin.native 当中,并且所有的接口都重做以贴合 Kotlin 通用框架的风格。通用标准库当中的一些 Native 特定的内容都置为 internal 或者 private,以此让我们的代码更标准化更容易移植。

如何吃螃蟹

详细信息请看这里 GitHub release page,当然您也可以下载二进制文件直接安装:macOSLinuxWindows。Linux Snap 包 在这里.