使用Index()迭代器进行解构

时间:2018-09-26 08:40:22

标签: kotlin

destructuring declarations纠缠在一起,以下使我感到困惑:

private data class TestData(var i: String, var j: Int) : Any() {}
private var mlist = mutableListOf<TestData>()

fun main(args: Array<String>) {

    mlist.add(TestData("Hi", 5))
    mlist.add(TestData("There", 53))
    mlist.add(TestData("Test", 2345))
    for ((i, v) in mlist.withIndex()) {

       println(i.toString() + " ok " + v.i + " " + v.component2())//Why does this line compile? 

       println("${i::class.qualifiedName}") // Printed classname is Int
   }
}

据我了解,代码会被破坏

fun <T> Array<out T>.withIndex(): Iterable<IndexedValue<T>> (source)

但是v.i为什么要编译?发生了什么事?

代码输出:

  

0 ok Hi 5
  kotlin.Int
  1 ok有53
  kotlin.Int
  2 OK测试   2345
  kotlin.Int

1 个答案:

答案 0 :(得分:2)

您的以下代码

for ((i, v) in mlist.withIndex()) {...

等于

for (item in mlist.withIndex()) {
    val i: Int = item.component1() //it is index in your list
    val v: TestData = item.component2()
    ...

如果您只想获取TestData个元素,请删除withIndex调用

for (item in mlist) {
    val i: String = item.component1()
    val v: Int = item.component2()
    ...

要使其正常工作,您的班级应为上述operator fun使用componentN。您的TestData类拥有它,因为您将其标记为data class

让我们回到让您感到困惑的代码行

println(i.toString() + " ok " + v.i + " " + v.component2())

我们已经知道-v: TestData。因此,i是您在主构造函数中使用var关键字提到的属性。

private data class TestData(var i: String, var j: Int)

也可以将其标记为val-在您的情况下没有意义,但是那样您就无法编辑此属性值(here,您可以阅读构造函数)。

private class TestData(i: String, j: Int) //this won't work in your case