一些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。怎么办呢?
答案 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
函数将允许您复制数据类,但使用新的不同值。