1、Kotlin - 1.3;

1、Kotlin - 1.3;

协程

  经过长时间的测试,协程发布了稳定版本, 这意味着从Kotlin 1.3开始,语言支持和API完全稳定。 协程概述页面。

  Kotlin 1.3Reflection API中引入了有关suspend-functions和协程支持的可调用引用。

Kotlin/Native

  Kotlin 1.3继续改进和完善Native项目,详细介绍

多平台项目

  在Kotlin 1.3中,已经完全重新设计了多平台项目的模型,以提高表达能力和灵活性,使得共享通用代码更加容易。 此外,现在还支持Kotlin/Native作为目标之一!

  与旧模型的主要区别在于:

  • 在旧模型中,需要将通用代码和特定于平台的代码放置在单独的模块中,并按预期的依赖关系进行链接。 现在,将通用的和特定于平台的代码放在同一模块的不同源根目录中,从而使项目更易于配置
  • 现在,存在针对不同支持平台的大量预设平台配置。
  • 依赖项配置已更改;现在为每个源根分别指定依赖项。
  • 现在可以在平台的任意子集之间共享源集(例如,在针对JS,Android和iOS的模块中,您可以拥有仅在Android和iOS之间共享的源集)。
  • 现在支持发布多平台库。

有关更多信息,参阅Multiplatform Programming文档

Contracts

  Kotlin编译器会进行大量的静态分析,以提供警告并减少样板。 最著名的功能之一具有基于执行类型检查自动执行强制转换的功能:

fun foo(s: String?) {    if (s != null) s.length // 编译器自动将's'强制转换为'String'}

  但是,一旦在单独的方法中进行了这些检查,所有智能转换就会消失:

fun String?.isNotNull(): Boolean = this != nullfun foo(s: String?) {    if (s.isNotNull()) s.length // 不会智能转换 :(}

  为了改善这种情况下的行为,Kotlin 1.3引入了称为Contracts的实验机制。Contracts允许函数以编译器可以理解的方式显式描述其行为。 当前,支持两种情况:

  • 通过声明函数的调用结果与传递的参数值之间的关系来改进智能分析:
fun require(condition: Boolean) {    // 这是一种语法形式,它告诉编译器:    // 如果此函数返回成功,则传递的'condition'为true    contract { returns() implies condition }    if (!condition) throw IllegalArgumentException(...)}fun foo(s: String?) {    require(s is String)    // s在此处智能转换为String,否则require将会抛出一个异常}
  • 在存在高阶函数的情况下改进变量初始化分析:
fun synchronize(lock: Any?, block: () -> Unit) {    // 它将告诉编译器:    // 此函数将在现在仅一次调用block    contract { callsInPlace(block, EXACTLY_ONCE) }}fun foo() {    val x: Int    synchronize(lock) {        x = 42 // 编译器知道传递给'synchronize'的lambda只会被调用一次,因此不会报告重新分配    }    println(x) // 编译器知道lambda将绝对会被调用,并执行初始化,因此此处将x视为已初始化}

  stdlib已经可以使用Contracts,这可以改善上述分析。 Contracts的这部分内容是稳定的,这意味着可以立即从改进的分析中受益,而无需任何其他选择:

fun bar(x: String?) {    if (!x.isNullOrEmpty()) {        println("length of '$x' is ${x.length}") // 自动转换为非null    }}

  可以为自己的函数声明Contracts,但是此功能是实验性的,因为当前语法处于早期原型状态,并且很可能会更改。 另外,当前Kotlin编译器并不会验证Contracts,因此编写正确和合理的Contracts程序员的责任。

when表达式捕获变量

  在Kotlin 1.3中,现在可以将when捕获为变量:

fun Request.getBody() =        when (val response = executeRequest()) {            is Success -> response.body            is HttpError -> throw HttpException(response.status)        }

  虽然已经可以在when之前提取变量,但是在whenval的范围已适当地限制为when的主体,因此可以防止名称空间污染。

可以在接口的伴生对象中声明@JvmStatic和@JvmField

  使用Kotlin 1.3,可以使用@JvmStatic@JvmField标记来标记接口的伴随对象的成员。 在类文件中,此类成员将被提升到相应的接口并标记为静态。

  例如以下Kotlin代码:

interface Foo {    companion object {        @JvmField        val answer: Int = 42        @JvmStatic        fun sayHello() {            println("Hello, world!")        }    }}

  相当于以下Java代码:

interface Foo {    public static int answer = 42;    public static void sayHello() {        // ...    }}

注解类中的嵌套声明

  在Kotlin 1.3中,注解类可以具有嵌套的类,接口,对象和伴生对象:

annotation class Foo {    enum class Direction { UP, DOWN, LEFT, RIGHT }        annotation class Bar    companion object {        fun foo(): Int = 42        val bar: Int = 42    }}

Function范型参数

  在Kotlin中,函数类型表示为具有不同数量参数的泛型类:Function0<R>Function1 <P0,R>Function2 <P0,P1,R>等。 ,当前以Function22结尾。

  Kotlin 1.3放宽了此限制,并增加了对Function更大支持的支持:

fun trueEnterpriseComesToKotlin(block: (Any, Any, ... /* 42 more */, Any) -> Any) {    block(Any(), Any(), ..., Any())}

内联类

内联类仅自Kotlin 1.3起可用,并且目前处于实验阶段。

  Kotlin 1.3引入了一种新的声明—inline class。 可以将内联类视为常规类的受限版本,特别是,内联类必须具有一个属性

inline class Name(val s: String)

  Kotlin编译器将使用此限制来积极优化内联类的运行时表示形式,并用基础属性的值替换其实例,并在可能的情况下删除构造函数调用,GC压力并启用其他优化:

fun main() {    // 在下一行中,没有构造函数调用发生,并且在运行时name仅包含字符串Kotlin    val name = Name("Kotlin")    println(name.s) }

无符号整数

无符号整数仅自Kotlin 1.3起可用,并且目前处于实验阶段

  Kotlin 1.3引入了无符号整数类型:

  • kotlin.UByte: 一个无符号的8-bit整数,范围从0到255
  • kotlin.UShort: 一个无符号的16-bit整数, 范围从0到65535
  • kotlin.UInt :一个无符号的32-bit整数, 范围从0到2^32 - 1
  • kotlin.ULong :一个无符号的64-bit整数, 范围从0到2^64 - 1
// 可以使用文字后缀来定义无符号类型val uint = 42u val ulong = 42uLval ubyte: UByte = 255u// 可以通过stdlib扩展将有符号类型转换为无符号类型,反之亦然:val int = uint.toInt()val byte = ubyte.toByte()val ulong2 = byte.toULong()// 无符号类型支持类似的运算符:val x = 20u + 22uval y = 1u shl 8val z = "128".toUByte()val range = 1u..5u

@JvmDefault

@JvmDefault仅自Kotlin 1.3起可用,目前处于实验阶段

  Kotlin面向广泛的Java版本,包括Java 6Java 7,其中接口不允许default方法。 为方便起见,Kotlin编译器可解决该限制,但该解决方法Java 8中引入的default方法不兼容。

  这是Java操作性的问题,因此Kotlin 1.3引入了@JvmDefault注解。 带有此注解的方法将作为JVMdefault方法生成:

interface Foo {    // 生成将作为带default关键字的方法    @JvmDefault    fun foo(): Int = 42}

@JvmDefault注解API对二进制兼容性有严重的影响。 在生产环境中使用@JvmDefault之前,请确保仔细阅读参考页。

标准库

多平台Random

  在Kotlin 1.3之前的版本中,没有统一的方法在所有平台上生成随机数-不得不求助于平台特定的解决方案,例如JVM上的java.util.Random。 此版本通过引入类kotlin.random.Random来解决此问题,该类在所有平台上都可用:

val number = Random.nextInt(42)  // number is in range [0, limit)println(number)

isNullOrEmpty/orEmpty扩展

  stdlib中已经存在某些类型的isNullOrEmptyorEmpty扩展。 如果接收者为null或为空,则第一个返回true;如果接收器为null,则第二个返回为空实例。 Kotlin 1.3在对象的ListMapArray上提供了类似的扩展。

在两个现有数组之间复制元素

  现有数组类型(包括无符号数组)的array.copyInto(targetArray,targetOffset,startIndex,endIndex)函数使在纯Kotlin中更容易实现:

val sourceArr = arrayOf("k", "o", "t", "l", "i", "n")val targetArr = sourceArr.copyInto(arrayOfNulls<String>(6), 3, startIndex = 3, endIndex = 6)println(targetArr.contentToString())sourceArr.copyInto(targetArr, startIndex = 0, endIndex = 3)println(targetArr.contentToString())

associateWith

  拥有键的List并想通过将这些键中的每个键与某个值相关联来构建映射是一种很常见的情况。 以前可以通过associate { it to getValue(it) }函数来做到这一点,但是现在引入了一种更高效,更容易探索的替代方法:keys.associateWith { getValue(it) }:

val keys = 'a'..'f'val map = keys.associateWith { it.toString().repeat(5).capitalize() }map.forEach { println(it) }

ifEmpty和ifBlank函数

  ListMap、对象数组、char序列和序列现在具有ifEmpty函数,该函数允许指定一个后备值,如果该值是空的,它将代替接收者使用:

fun printAllUppercase(data: List<String>) {    val result = data    .filter { it.all { c -> c.isUpperCase() } }        .ifEmpty { listOf("<no uppercase>") }    result.forEach { println(it) }}printAllUppercase(listOf("foo", "Bar"))printAllUppercase(listOf("FOO", "BAR"))

  Char序列和字符串还具有if Blank扩展名,该扩展名与Empty作用相同,但检查字符串是否全部为空格而不是空:

val s = "    \n"println(s.ifBlank { "<blank>" })println(s.ifBlank { null })

一些小的改变

  • Boolean类型有伴生对象
  • Any?.hashCode()扩展函数,如果为null返回0
  • Char现在提供了MIN_VALUE/MAX_VALUE常量
  • 基本类型伴生对象中的SIZE_BYTESSIZE_BITS常量。

工具

IDE中的代码样式支持

  Kotlin 1.3引入了对IDE推荐代码风格的支持。

kotlinx.serialization

  kotlinx.serialization是一个库,为Kotlin中的对象(反序列化)提供多平台支持。 以前,这是一个单独的项目,但是从Kotlin1.3开始,它与Kotlin编译器发行版一起发布,与其他编译器插件同等。

脚本更新

请注意,脚本编写是一项实验性功能,这意味着未提供API的兼容性保证。

  Kotlin 1.3继续发展和改进脚本API,引入了一些实验性的脚本自定义支持,例如添加外部属性,提供静态或动态依赖关系等。

Scratch支持

  Kotlin 1.3引入了对可运行Kotlin暂存文件的支持。 Scratch文件是带有.kts扩展名的kotlin脚本文件,可以直接在编辑器中运行并获取结果。

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部