您的位置:首页 > 其它

Kotlin-解构声明

2017-07-05 13:47 309 查看
有时候我们把一个对象解构成几个变量,这种方式是非常便利的,例如:

val(name,age)=person


这种语法叫解构声明(Destructuring Declarations),解构声明一次性生成了多个变量,在上个例子中,我们一次声明了两个变量:name和age,我们可以直接用:

println(name);
println(age);


解构声明,在编译之后变成了下面的代码:

val name=person.component1()
val age=person.component2()


component1()和component2()函数是在Kotlin中广泛使用的原则与公约中的另外一个例子(具体查看+和*for-loops等),任何对象都可以放在解构声明的右边来被解构,解构多少变量就有多少类似component2的函数被调用。它们可以是component3和component4一直下去。

==注意:componentN函数需要被operator标识了才允许被解构==

解构声明同样也适用于for循环中,

for((a,b) in collection){...}


变量a和b就是调用集合元素的component1()和component2()来获得值.

示例:一个函数返回两个值

现在我们来说下一个函数返回两个值的事,例如,一个结果对象和一个排序状态,一般的做法就是定义一个数据类然后返回他的实例:

data class Result(val result:Int,val status:Status)
fun function(...):Result{
//...
return Result(result,status)
}

//现在我们可以这样做
val(result,status)=function(...)


这是因为在结构声明的作用下,会自动生成具有componentN()函数的数据类

==注意:在这里,我们同样也可以使用Pair类和函数来返回Pair

示例:解构声明与Maps

遍历Map最好的方式可能是这样:

for((key,value) in map){
//...
}


要使上面这个例子可以使用,我们还需要这一步:

- 在当前的Map中需要有迭代器(iterator())函数

- 当前的元素对都需有component1()和component2()函数

然而可喜的是,在标准库中已经提供了这样的拓展:

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()


所以你可以尽情的在for循环中使用解构声明(对于数据类的集中都同样使用)

用下划线(_)标示未使用变量(版本1.1后)

当你在解构声明中不想用一个变量时,可以用下划线(_)来代替:

val(_,status)=getResult()


在Lambds中解构(版本1.1后)

在lambdas参数中也可以使用解构声明语法,如果lambdas有Pair的参数(或Map.Entry或其他有componentN函数的类型也可以),你可以将几个参数替换为括号中的参数:

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


==注意:声明两个参数和解构声明一个参数之间是有区别的:==

{ a -> ... } // one parameter
{ a, b -> ... } // two parameters
{ (a, b) -> ... } // a destructured pair
{ (a, b), c -> ... } // a destructured pair and another parameter


如果不使用一个解构组合中的一个参数,可以使用下划线(_)来代替,避免创建它的名称:

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


在特定的组件中,你可以指定整个解构参数的类型,

map.mapValues { (_, value): Map.Entry<Int, String> -> "$value!" }

map.mapValues { (_, value: String) -> "$value!" }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: