Kotlin-其他特性(持续更新)

开始

Kotlin 提供了很多特性,可以帮助开发者提高开发效率。本篇博客将介绍这些特性。

下面例子都来自 Kotlin 的官方文档。

解构声明

解构声明,英文叫做 Destructuring Declarations,可以减少我们创建的一些”无意义”的类,从而让我们的代码变得更加简洁。具体使用场景如下:

当我们需要在类与类之间传递数据的时候,而且数据不止一种类型或者数据不止一个,这个时候我们可以要创建一个类,然后声明对应的属性。某种意义上来说,这个类是多余的,因为它仅仅只是起到了传递的作用。

于是在 Java 中,系统提供了 Pair<F,S>,这个类的主要作用就是用来存储两个数据,当我们要传递两个数据但是又不想为这两个数据创建一个新的类,这个时候,Pair 类是一个不错的选择,代码如下:

1
2
3

Pair<Integer,String> pair = Pair.create(1,"壹");
//直接传递 pair 对象。

虽然 Pair 类看上去不错,但是也有一些弊端,一是只能传递两个,而是代码可读性不是很好。是用解构声明,就能很轻松的解决这两个问题。代码如下:

1
2
3
4
5
6
7
8
9
10
11

//Person 是一个对象的实例,且不仅仅只有 name 和 age 这两个属性
val (name, age) = person

//编译后的伪代码
val name = person.component1()
val age = person.component2()

//分别输出 name 和 age
println(name)
println(age)

从上面的代码中可以看到,解构函数可以将某种类型的对象实例中的某几个属性单独获取出来,获取的策略是使用 componentN() 函数。解构声明不仅可以在变量上声明,还可以在其他地方声明。具体代码如下:

1
2
3
4
5
6

//在循环中使用解构声明
for (a, b in collection) { ... }

//在遍历 Map 的时候使用解构声明
for ((key, value) in map) { ... }

当我们遍历集合的时候使用解构声明,其对应的值是集合中对象所声明的 componentN(),而 Map 不一样,Kotlin 默认帮我们实现了获取 Key 和 Value 的 compentN() 函数,所以我们可以直接遍历一个 Map 的 Key 和 Value。

通过上面的例子,不难发现,解构函数和 componentN() 函数有分不开的关系,而且和 componentN() 函数声明的顺序也有很大的关系,当我们想绕过某些属性的时候可以使用 _ 来实现”占位子”的特性。具体代码如下:

1
2
3
4
5

//假设 Person 类中有 3 个属性分别是: id name age
//我们想拖过解构声明来获取 person 对象中的 name 和 age

val(_, name, age) = person

解构声明还可以在 lambda 表达式中使用,更加进一步的优化我们的代码。具体代码如下:

1
2
3
4
5
6
7
8
9
10

//遍历 Map
map.mapValues{ entry -> "${entry.value}!" }
map.mapValues{ (key, value) -> "$value" }

//声明解构对和声明参数之间的区别
{ a -> ... } //一个参数
{ a, b -> ... } //两个参数
{ (a, b) -> ... } //一个解构对
{ (a, b), c -> ... } //一个解构对和一个参数

集合

和大多数语音不同,Kotlin 提供了可变和不可变的两种结合类型,拿 List 举例,默认情况下 List 类型创建的是一个只读的集合,而 MutableList 类型创建的就是一个可变的集合对象。Map 和 Set 也是一样。

为了方便我们创建集合,Kotlin 提供了很多有用的方法,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

//创建一个只读 List
val readOnlyList = listOf(1, 2, 3)

//创建一个可读可写的 List
val readWriteList = muutableListOf(1, 2, 3)

//编译不通过,因为readOnlyList 是只读的所以无法修改其数据
readOnlyList.clear()

//将一个可变集合 copy 成一个不可变的集合
val _items = mutableListOf(1, 2, 3)
val items: List<Int> = _items.toList()

//List 本身还提供了很多有用的方法
val items = listOf(1, 2, 3, 4)
items.first()
items.last()
items.filter { it % 2 == 0 }

val rwList = mutableListOf(1, 2, 3, 4)
rwList.requireNoNulls()
if (rwList.none { it > 6 }) println("No items above 6")
val item = rwList.firstOrNull()


//Map 的一些使用方法

范围