常用 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更加简洁和具有连续性
- 如果默认的可见效修饰符会将其暴露给公共API,则需要添加显示的可见性修饰符,以减少不经意的失误导致可见性的泄漏
- 对于会暴露给公共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