Kotlin - 循环中的解构不起作用 - var无法访问

时间:2018-01-23 07:56:40

标签: kotlin

一些background

val (name, age) = person 

此语法称为解构声明。它会同时创建多个变量(更正,创建多个值)。

解构声明也适用于for循环:当你说:

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

让我们看看我有一个列表项:

    @Parcelize
data class MyModel(
        var name: String = "",
        var is_locked: Boolean = true,
        var is_one_size: Boolean = false,
) : Parcelable

现在我已经获得了一个“MyModel”类列表,我试图像这样循环它们:

private fun initMyModelList(model: MutableList<MyModel>) {
 //i want to access is_locked from here with destruction but i cant ? IDE telling me the type is an int but its clearly defined as a Boolean
        for((is_locked) in model){
          //what i want to do in here is access the is_locked var of the model list and change all of them in a loop. im trying to use Destructuring in loop as a conveience. why is it not working ?
//how can i make the call signature look like this--- > is_locked = true instad of model.is_locked =true 
        }
}

我想做的就是能够在循环中调用is_locked = true而不是model.is_locked = true。怎么办呢?

3 个答案:

答案 0 :(得分:4)

  

此语法称为解构声明。它同时创建多个变量。

它不会创建多个变量,它会捕获多个值。您正在使用值,而不是引用,正如您的来源进一步说明的那样:

  

解构声明编译为以下代码:

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

最接近你想要的是这个自定义扩展功能:

inline fun <E> Iterable<E>.withEach(block: E.() -> Unit) {
    forEach {
        it.block()
    }
}

像这样使用:

model.withEach {
    is_locked = true
}

在你提出强制性问题之前“为什么这不包含在stdlib中?”认为函数式编程通常是关于转换不可变类型。基本上,我在这里做的是鼓励一个坏习惯。

答案 1 :(得分:3)

基本上,这是不可能的,因为你的代码被编译成类似的东西:

for (m in models) {
    val is_locked = m.component1()
    ...
}

这意味着您创建了一个无法重新分配的本地属性。但你可以这样做:

for (m in model) {
    with(m) {
        is_locked = true
    }
}

是的,它并不完美,但可以通过扩展方法进行改进:

fun <T> List<T>.forEachApply(block: T.() -> Unit) {
    forEach(block)
}

private fun initMyModelList(model: MutableList<MyModel>) {
    model.forEachApply { 
        is_locked = true
    }
}

答案 2 :(得分:1)

您可以在循环中使用解构,只作为只读值。

data class Stuff(val name: String, val other: String)

fun doStuff() {
    val stuff = Stuff("happy", "day")
    val stuffs = listOf(stuff)

    for ((name) in stuffs) {
        println(name)
    }
}

运行该方法会向控制台输出“happy”。 Baeldung显示了使用它的一个例子here

数据类是不可变的最佳实践,因此我会尝试将数据类重写为不可变的。 .copy函数将允许您复制数据类,但使用新的不同值。