Kotlin 各版本新特性
一、1.4.0
1. 支持SAM语法
SAM 即 Single Abstract Method, 自打 Java 8起,lambda语法,使得java语法更加简洁。SAM就是其中的亮点之一。我们先来看一下,java的实现方式对比:
interface SAM{
void test(int i);
}
public class Test {
public static void main(String[] args) {
// 普通方式
testSAM(new SAM() {
@Override
public void test(int i) {
}
});
// lambda方式
testSAM(i -> {
});
}
private static void testSAM(SAM sam){
}
}
从代码可以看得出,lambda的实现方式,更为简洁,当然不可避免的失去一定的可读性,但利大于弊,SAM的实现方式,还是更值得推荐使用。
而在Kotlin 1.4之前,纯kotlin是无法实现这种效果,除非你引用的是符合SAM标准的Java接口,实现方式如下:
val test: SAM = SAM { }
如果在1.4前,定义一个符合SAM标准的kotlin接口,实现方式是怎么样的呢?让我们看看代码:
interface Test {
fun test(i: Int)
}
val test = object : Test {
override fun test(i: Int) {}
}
1.4之后,变成这样:
fun interface Test {
fun test(i: Int)
}
val test = Test { }
是不是简洁了许多?仔细点的学者可能已经注意到区别,在1.4之后,想让SAM能实现lambda效果的话,需要在interface关键字前再加一个关键字fun,标记该接口符合SAM标准,可以转成lambda格式。
这时,有些比较调皮的人,就会想,那我一边给接口加上fun关键字,又故意再给加个方法,破坏SAM标准,又会怎么样?如下所示:
fun interface Test {
fun test(i: Int)
fun test2(i: Int)
}
val isEven = Test { }
结果,在意料之中,编辑器会报错。
2. 带默认值的多参方法的调用优化。
Kotlin1.4,增加了,对带有默认值的多参数方法的调用优化。在1.4之前,在调用,带有默认值的多参方法,并且,需要全赋值时,你不能只显示的,给前面几个参数,指定参数名。这句听起来不好理解。
我们以下面的代码为例, test方法**依次有三个参数,a、b、c。**如果你给a指定了参数名,那b、c也必须指定。如果你给b,指定了参数名,那c也必须指定。也即是说,**参数名的指定,前一个有的,后一个必须也有。**那么,指定参数名的逻辑,在1.4之前,我们一般都是从后开始指定。但在1.4中,去掉了这个限制,你可以只给a或只给b,指定参数名,而无需给其后的其它参数指定参数名。 这也使得调用更加人性化。
fun test(a: Int=0, b: Int=0, c: Int=0) {}
fun doTest() {
// 1.4 新增语法允许的
test(a = 1, 2, 3) // 指定第一个参数名
test(1, b = 2, 3) // 只指定赋值第二个参数名。
// 1.4前也可以,编译通过
test(a = 3) // 只赋值指定参数,可以
test(c = 3) // 只赋值指定参数,可以
test(1, b = 2) // 只赋值指定参数,可以
test(1, 2, c = 3) // 只赋值,指定参数名前的所有参数(a,b),可以。
test(1, b = 2, c = 3) // 只赋值,后2个,可以。
test(1, c = 2, b = 3) // 只赋值,后2个,并混合位置,可以。
test(c = 3, b = 2, a = 3) // 三个都指定,然后混位置,可以
// 1.4后也不行,编译失败
test(1, a = 2, 3) // 把第一个参数名,指定并放在第二个位置赋值,不行。
}
3. 尾部逗号(Trailing Comma)。
当我们在赋值参数、定义参数、调用方法时,如果在参数后,多加一个 , 逗号,在1.4之前,是编译不过去的。比如,这样子:
data class Foo(val a: Int = 0,
val b: Int= 0,
)
为什么,我们要在最后一个参数后面加逗号呢?因为,这个类有可能后续会增加字段,亦或是,我们直接复制粘贴上一个字段,就会多出一个逗号。在1.4之前还得去删除掉,在你增加个新字段时,又得加上,这显得就没啥必要。在1.4之后,这样的语法也是支持的,新增字段时,直接鼠标点击 字段 b 那一行,ctrl+d,创建个新的字段,再改字段名、类型、默认值就行,不需要再去写个val和逗号。这个特性,也使得kotlin更加人性化。
4.去掉break/continue在when语句中使用时,必须携带冗余label的问题。
这是1.4之前的
fun test(xs: List<Int>) {
LOOP@for (x in xs) {
when (x) {
2 -> continue@LOOP
17 -> break@LOOP
else -> println(x)
}
}
}
这是1.4+的
fun test(xs: List<Int>) {
for (x in xs) {
when (x) {
2 -> continue
17 -> break
else -> println(x)
}
}
}
通过对比,我们可以看出来,1.4+后,使用continue和break变得更加简洁了。
参考资料