Kotlin

常用 Kotlin 1.4 新特性介绍

2020-11-06  本文已影响0人  两三行代码

Trailing comma

在多行编辑函数参数的时候,最后一个参数最后总是不能添加逗号,会显得不太方便。

 fun main() {  
   val person = Person("bennyhuo",30)
 }

现在则可以保留最后一个逗号,简单但是有效:

 fun main() {  
   val person = Person("bennyhuo",30,)
 }

SAM conversions for Kotlin interfaces

根据新推导算法,对于只有调用单一Java接口方法的Java方法才有SAM转换有了更加简单的写法,

runAction { println("Hello, Kotlin 1.4!") }

在Kotlin方法之前则需要

 runAction(Action { println("Not good..") })

Explicit API mode for library authors

在此种模式下,编译器在执行传统检查基础上会帮助库API更加简洁和具有连续性

Mixing named and positional arguments

在kotlin1.3中,当你调用一个命名参数的函数时,你必须把非具名参数放置在第一个具名参数前,比如你可以调用f(1, y = 2),但是不能调用f(x = 1, 2)。

在kotlin1.4开始则没有这种限制,如下

fun reformat(
    str: String,
    uppercaseFirstLetter: Boolean = true,
    wordSeparator: Char = ' '
) {
    // ...
}

//Function call with a named argument in the middle
reformat("This is a String!", uppercaseFirstLetter = false , '-')

References to functions with default argument values

现在可以对具有默认参数值的函数使用可调用引用,如下

fun foo(i: Int = 0): String = "$i!"

fun apply(func: () -> String): String = func()

fun main() {
    println(apply(::foo))
}

而在之前则需要一下方式重写

// some new overload
fun applyInt(func: (Int) -> String): String = func(0)

Using break and continue inside when expressions included in loops

在kotlin1.4,无需标记就可以在循环体内的when表达式内使用break和continue

fun test(xs: List<Int>) {
    for (x in xs) {
        when (x) {
            2 -> continue
            17 -> break
            else -> println(x)
        }
    }
}

在kotlin1.3,不能在循环体的when表达式中使用非限定的break和continue。如果你想使用break或者continue,则必须要标记,但是这样标记繁琐

fun test(xs: List<Int>) {
    LOOP@for (x in xs) {
        when (x) {
            2 -> continue@LOOP
            17 -> break@LOOP
            else -> println(x)
        }
    }
}

Function references in Unit-returning functions

在kotlin1.4可以通过可调用引用的方式,使unit返回类型的函数引用任意返回类型的函数,在kotlin1.3中则只能使用lambda

fun foo(f: () -> Unit) { }
fun returnsInt(): Int = 42

fun main() {
    foo { returnsInt() } // this was the only way to do it  before 1.4
    foo(::returnsInt) // starting from 1.4, this also works
}

Better inference for delegated properties

在kotlin1.3中,在分析key关键字之后的代理属性表达式时,代理属性类型并不会进行推导。kotli1.3中以下代码并不会通过编译,但是现在则可以

import kotlin.properties.Delegates

fun main() {
    var prop: String? by Delegates.observable(null) { p, old, new ->
        println("$old → $new")
    }
   // kotlin 1.3
  // var prop: String? by Delegates.observable<String?>(null) { p, old, new ->
   //     println("$old → $new")
   // }
    prop = "abc"
    prop = "xyz"
}

Smart casts for callable references

在kotlin1.3中,不能直接引用智能转换类型的成员,但是kotlin1.4则可以便捷访问

sealed class Animal
class Cat : Animal() {
    fun meow() {
        println("meow")
    }
}

class Dog : Animal() {
    fun woof() {
        println("woof")
    }
}

fun perform(animal: Animal) {
    val kFunction: KFunction<*> = when (animal) {
        is Cat -> animal::meow
        is Dog -> animal::woof
    }
    kFunction.call()
}

fun main() {
    perform(Cat())
}

在animal变量被智能转换为Cat和Dog类型之后,则可以使用不同的成员引用animal::meow animal::woof

Smart casts for a lambda’s last expression

在kotlin1.3,不会去lambda内最后一条表达式的类型,必须要显式指定

val result = run {
    var str = currentValue()
    if (str == null) {
        str = "test"
    }
    str // the Kotlin compiler knows that str is not null here
}
// The type of 'result' is String? in Kotlin 1.3 and String in Kotlin 1.4
上一篇下一篇

猜你喜欢

热点阅读