重拾Kotlin(19)-中缀调用、解构声明
2019-06-12 本文已影响10人
业志陈
一、中缀调用
可以以以下形式创建一个 Map 变量
fun main(args: Array<String>) {
val maps = mapOf(1 to "leavesC", 2 to "ye", 3 to "czy")
maps.forEach { key, value -> println("key is : $key , value is : $value") }
}
使用 “to” 来声明 map 的 key 与 value 之间的对应关系,这种形式的函数调用被称为中缀调用
中缀调用可以与只有一个参数的函数一起使用,无论是普通的函数还是扩展函数。中缀符号需要通过 infix 修饰符来进行标记
fun main(args: Array<String>) {
val pair = 10 test "leavesC"
val pair2 = 1.2 test 20
println(pair2.javaClass) //class kotlin.Pair
}
infix fun Any.test(other: Any) = Pair(this, other)
对于 mapOf
函数来说,它可以接收不定数量的 Pair
类型对象,因此我们也可以通过自定义的中缀调用符 test
来创建一个 map 变量
public fun <K, V> mapOf(vararg pairs: Pair<K, V>): Map<K, V> =
if (pairs.size > 0) pairs.toMap(LinkedHashMap(mapCapacity(pairs.size))) else emptyMap()
val map = mapOf(10 test "leavesC", 20 test "hello")
二、解构声明
有时会有把一个对象解构成多个变量的需求,在 Kotlin 中这种语法称为解构声明
例如,以下例子将 Person 变量结构为了两个新变量:name 和 age,并且可以独立使用它们
data class Person(val name: String, val age: Int)
fun main(args: Array<String>) {
val (name, age) = Person("leavesC", 24)
println("Name: $name , age: $age")
//Name: leavesC , age: 24
}
一个解构声明会被编译成以下代码:
val name = person.component1()
val age = person.component2()
其中的 component1()
和 component2()
函数是在 Kotlin 中广泛使用的约定原则的另一个例子。任何表达式都可以出现在解构声明的右侧,只要可以对它调用所需数量的 component
函数即可
需要注意的是,componentN()
函数需要用 operator
关键字标记,以允许在解构声明中使用它们
对于数据类来说,其自动生成了 componentN()
函数,而对非数据类,为了使用解构声明,需要我们自己来手动声明函数
class Point(val x: Int, val y: Int) {
operator fun component1() = x
operator fun component2() = y
}
fun main(args: Array<String>) {
val point = Point(100, 200)
val (x, y) = point
println("x: $x , y: $y")
//x: 100 , y: 200
}
如果我们需要从一个函数返回两个或者更多的值,这时候使用解构声明就会比较方便了
这里使用的是标准类 Pair 来包装要传递的数据,当然,也可以自定义数据类
fun computer(): Pair<String, Int> {
//各种计算
return Pair("leavesC", 24)
}
fun main(args: Array<String>) {
val (name, age) = computer()
println("Name: $name , age: $age")
}
此外,解构声明也可以用在 for 循环中
val list = listOf(Person("leavesC", 24), Person("leavesC", 25))
for ((name, age) in list) {
println("Name: $name , age: $age")
}
对于遍历 map 同样适用
val map = mapOf("leavesC" to 24, "ye" to 25)
for ((name, age) in map) {
println("Name: $name , age: $age")
}
同样也适用于 lambda 表达式
val map = mapOf("leavesC" to 24, "ye" to 25)
map.mapKeys { (key, value) -> println("key : $key , value : $value") }
如果在解构声明中不需要某个变量,那么可以用下划线取代其名称,此时不会调用相应的 componentN()
操作符函数
val map = mapOf("leavesC" to 24, "ye" to 25)
for ((_, age) in map) {
println("age: $age")
}