如何修复此特定的“无法重新分配 Val”错误?

How can I fix this particular "Val cannot be reassigned" error?

提问人:Dylon Jaynes 提问时间:4/12/2022 最后编辑:Dylon Jaynes 更新时间:4/12/2022 访问量:487

问:

我有这段代码,它一直给我一个“Val cannot be reassigned”错误,但我似乎无法将变量更改为 var 而不是 val。我只是希望能够为我的单元格引用设置一个字符串值,以便我以后可以像这样访问这些值。myStringsArrayList.add(deviceData.cellOne)

这是我的代码:

val cells = listOf(
            deviceData.cellOne,
            deviceData.cellTwo,
            deviceData.cellThree,
            deviceData.cellFour,
            deviceData.cellFive,
            deviceData.cellSix,
            deviceData.cellSeven,
            deviceData.cellEight,
            deviceData.cellNine,
            deviceData.cellTen,
            deviceData.cellEleven,
            deviceData.cellTwelve,
            deviceData.cellThirteen,
            deviceData.cellFourteen
        )

        for ((i, cell) in cells.withIndex()) {
            val value = data[2 + i].toDouble() / 100 + 3.52
            val cellNumberString = (i + 1).toString()
            val formattedString = "Cell $cellNumberString: %.2fV".format(value)
            cell = formattedString // THIS IS WHERE THE PROBLEM IS (cell is a val)
        }

有谁知道我如何解决这个问题并实现我想要的功能?

我尝试使用一个,但它似乎没有按照我想要的方式工作。listIterator()

这是我对 :listIterator()

val cells = mutableListOf(
            deviceData.cellOne,
            deviceData.cellTwo,
            deviceData.cellThree,
            deviceData.cellFour,
            deviceData.cellFive,
            deviceData.cellSix,
            deviceData.cellSeven,
            deviceData.cellEight,
            deviceData.cellNine,
            deviceData.cellTen,
            deviceData.cellEleven,
            deviceData.cellTwelve,
            deviceData.cellThirteen,
            deviceData.cellFourteen)

        val iterate = cells.listIterator()
        while (iterate.hasNext()) {
            var cell = iterate.next()
            val value = data[2 + iterate.nextIndex()].toDouble() / 100 + 3.52
            val cellNumberString = (iterate.nextIndex() + 1).toString()
            val formattedString = "Cell $cellNumberString: %.2fV".format(value)
            cell = formattedString
        }
人造人 科特林 不变性 无功型 可变

评论

1赞 CommonsWare 4/12/2022
尝试 ,您的转换逻辑在 lambda 中的位置。val cells = listOf().map { }map
0赞 Michel Fortes 4/12/2022
看看这个答案。这可能会有所帮助。
0赞 Dylon Jaynes 4/12/2022
@MichelFortes我通读了那篇帖子并尝试使用 a,但它并没有真正起作用。我将对我的问题进行编辑,以便您查看。也许我没有正确使用它?我需要它来更改我的自定义 DeviceData 对象中的变量,但似乎我无法做到这一点。listIterator()

答:

3赞 cactustictacs 4/12/2022 #1

你不能把它变成一个,反正也没有理由!var

for ((i, cell) in cells.withIndex()) {
    ...
    cell = formattedString // THIS IS WHERE THE PROBLEM IS (cell is a val)
}

你正在集合上创建一个带有索引的循环,并为其提供一个代码块来为每个循环运行。因此,当循环运行时,系统会提供两个参数 - 集合中的当前项及其在该集合中的索引。for

这些只是在循环中使用的内部变量 - 您不能重新分配它们,因为它们是传入的值。即使可以,也只是更改了这些局部变量的值。

您可能正在尝试做的是更新列表,将当前项目放入循环中,在 中找到它并替换它。您必须实际更新才能做到这一点!更改列表本身。你可以这样做 - 但由于您当前正在迭代该集合,因此不应修改它!cellscellscellscells[i] = formattedStringcells

您可以复制源列表,但典型的 Kotlin 方法是创建一个新列表,使用 (转换值):map

cells.mapIndexed { i, cell ->
    val value = data[2 + i].toDouble() / 100 + 3.52
    val cellNumberString = (i + 1).toString()
    // last expression is the return value, i.e. the formatted string
    "Cell $cellNumberString: %.2fV".format(value)
}

这将吐出一个新的(不可变的)列表,其中每个单元格都已映射到该格式化的字符串版本。

您可以创建一个并重新分配它:cellsvar

cells = cells.mapIndexed { ... }

或者只是在初始化 时链接映射调用,以便最终结果是分配的内容:val

val cells = listOf(
    ...
).mapIndexed { ... }

但无论如何,你实际上并没有在那个循环中使用,只是使用索引来生成值。您可以创建如下列表cell

val data = List(14) { i ->
    val value = data[2 + i].toDouble() / 100 + 3.52
    // you can calculate the index inside the string by using braces
    "Cell ${i + 1}: %.2fV".format(value)
}

这完全取决于您是否需要保留该值列表以用于任何内容(如果是,请使用它来创建另一个列表)devicedata

评论

0赞 Dylon Jaynes 4/12/2022
哇,我非常喜欢这个解决方案!我最终按照您的建议使用了链式地图调用,效果很好!
1赞 Michel Fortes 4/12/2022 #2

您可能希望以这种方式使用 Interator:

val list = mutableListOf("One", "Two", "Three", "Four")
println(list.joinToString(" "))

val iterator = list.listIterator()
while(iterator.hasNext()) {
    val value = iterator.next()
    if (value == "Two") {
        iterator.set("xxxxxx")
    }
}
println(list.joinToString(" "))

使用“set”方法。

评论

0赞 Dylon Jaynes 4/12/2022
感谢您的回答!我实际上完全忘记了有一个 set() 函数!