Kotlin:迭代对象的组件

时间:2016-07-31 20:26:04

标签: kotlin

每个数据类对象都有一个组件,用于每个属性,如component1,component2等。 我想知道在Kotlin中是否有任何方法可以迭代一个类的每个组件。 说我上课了:

class User(age:Int, name:String)

我可以这样做:

for(component in aUserObject){
    //do some stuff with age or name
}

4 个答案:

答案 0 :(得分:29)

首先,componentN属性仅适用于数据类,而不适用于每个对象。

没有专门用于迭代组件的API,但您可以使用Kotlin reflection迭代任何类的属性:

class User(val age: Int, val name: String)

fun main(args: Array<String>) {
    val user = User(25, "Bob")
    for (prop in User::class.memberProperties) {
        println("${prop.name} = ${prop.get(user)}")
    }  
}

答案 1 :(得分:0)

此外,您可以将Properties Delegation与内置委托“ by map”一起使用。对于某些简单的统计信息类,它非常有用。

class DbUsingStat {
  private val map = mutableMapOf(
    "removed" to 0,
    "updated" to 0,
    "skipped" to 0
  )

  var removed by map
  var updated by map
  var skipped by map

  fun asMap() : Map<String, Int> = map.toMap()
}

...
...


val someStatistic = DbUsingStat().apply {
  skipped = 5
  removed = 10
  updated = 1505
}

for((k, v) in someStatistic.asMap())
  println("$k: $v")

答案 2 :(得分:0)

这是一个主意...我对此不满意...但仍然如此。

它有一些优点和缺点:

    优点:
    • 类型安全/编译时检查
      • 在数据类中添加字段/从数据类中删除字段会导致字段迭代站点上的编译器错误
    • 不需要样板代码
  • 缺点:
    • 如果为参数定义了默认值,则无法使用

声明:

data class Memento(
    val testType: TestTypeData,
    val notes: String,
    val examinationTime: MillisSinceEpoch?,
    val administeredBy: String,
    val signature: SignatureViewHolder.SignatureData,
    val signerName: String,
    val signerRole: SignerRole
) : Serializable

在所有字段中重复:

val iterateThroughAllMyFields: Memento = someValue
Memento(
    testType = iterateThroughAllMyFields.testType.also { testType ->
        // do something with testType
    },
    notes = iterateThroughAllMyFields.notes.also { notes ->
        // do something with notes
    },
    examinationTime = iterateThroughAllMyFields.examinationTime.also { examinationTime ->
        // do something with examinationTime
    },
    administeredBy = iterateThroughAllMyFields.administeredBy.also { administeredBy ->
        // do something with administeredBy
    },
    signature = iterateThroughAllMyFields.signature.also { signature ->
        // do something with signature
    },
    signerName = iterateThroughAllMyFields.signerName.also { signerName ->
        // do something with signerName
    },
    signerRole = iterateThroughAllMyFields.signerRole.also { signerRole ->
        // do something with signerRole
    }
)

答案 3 :(得分:0)

在 kotlin 中,您可以通过以下方式执行此操作,通过迭代对象字段,在其中使用反射。

 private fun prepareData(covidResponse: CovidResponse) {
    for (field in covidResponse.javaClass.declaredFields){
              responseList.add(field as Object)
    }
}