解构声明(Destructuring Declarations)

解构声明的概念和作用

把一个对象成员解构(destructure)成多个变量,称为解构声明(destructuring declaration)。

component1(),component2()等函数是Kotlin约定的操作符,componentN是操作符(类似加减乘除的运算符),重载操作符必须要用operator修饰以允许使用

class MyPair<K, V>(val first: K, val second: V) {
operator fun component1(): K {
return first;
}

operator fun component2(): V {
return second;
}
}
fun main(args: Array<String>) {
val pair = MyPair(1, "one")
val (num, name) = pair
println("num = $num, name = $name")

}

数据类(data class)

编译器会为数据类(data class)自动声明/定义componentN()函数,可直接使用解构声明。

data class Person (val name: String,val age: Int,val addr:String){
}

fun main(args: Array<String>) {
   var person = Person("Jone", 20, "henan")
   println("name:${person.component1()},age:${person.component2()},addr:${person.component3()}")
}

函数返回多个变量(Return Values)

 如果需要一个函数返回多个变量,Kotlin最简洁的实现是声明一个数据类并返回其实例对象。

data class Result(val result: Int, val message: String)

fun getResult(): Result {
    return Result(1, "ok")
}

fun main(args: Array<String>) {
    val (result, message) = getResult();
    println("result=$result,message=$message")

}

 

for循环-解构声明

 var personA: Person = Person("Door", 22, "ShanDong")
 var personB: Person = Person("Green", 30, "BeiJing")
 var personC: Person = Person("Dark", 23, "YunNan")
 var personD: Person = Person("Tool", 26, "GuanDong")
 var personE: Person = Person("Mark", 24, "TianJin")
 var pers = listOf(personA, personB, personC, personD, personE)
 for ((name, age,addr) in pers) {
     println("name:$name,age:$age,addr:$addr")
 }

 

自定义componentN

在Kotlin数据类中,编译器会根据主构造器中声明的全部属性, 自动推断产生componentN() 函数,但是对于普通类的成员属性,编译器并不会自动推断产生componentN() ,此时componentN()需要我们自己定义了。

data class Person (val name: String,val age: Int,val addr:String){
    var mobile: String ?= null
    operator fun component4(): String {
        return this.mobile!!
    }
}

fun main(args: Array<String>) {
    var person: Person = Person("Jone", 20, "ShangHai")
    person.mobile = "147323"
    var (name, age, addr, mobile) = person
    println("name: $name, age: $age, addr: $addr, mobile: $mobile")
}

对于自定义的componentN(),componentN()函数需要标记为 operator,才可以在解构声明中使用

Map-解构声明

在Kotlin的标准库中,对Map实现了这些扩展函数:

operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = entrySet().iterator()

operator fun <K, V> Map.Entry<K, V>.component1() = getKey()

operator fun <K, V> Map.Entry<K, V>.component2() = getValue()

 也就是意味着:
- 实现 iterator() 函数, 使得 map 成为多个值构成的序列
- 实现 component1() 和 component2() 函数, 使得 map 内的每个元素成为一对值

这样,我们可以对 map 的for循环中自由地使用解构声明,例如:

fun main(args:Array<String>){
    val map = hashMapOf<String, Int>()
    map.put("one", 1)
    map.put("two", 2)
    for ((key, value) in map) {
        println("key = $key,value = $value")
    }
}

 如果解构的参数中的一个组件未使用,那么可以将其替换为下划线,以避免编造其名称:

map.mapValues { (_, value) -> println("$value!") }

可以指定整个解构的参数的类型或者分别指定特定组件的类型:
map.mapValues { (_, value:Int) -> println("$value!") }



 

 

 

 

 


posted @ 2018-05-11 10:47  南极冰川雪  阅读(470)  评论(0编辑  收藏  举报