【问题标题】:Kotlin: Iterate over components of objectKotlin:迭代对象的组件
【发布时间】:2016-07-31 20:26:04
【问题描述】:

每个数据类对象对于每个属性都有一个组件,例如组件 1、组件 2 等。 我想知道 Kotlin 中是否有任何方法可以遍历类的每个组件。 说我有课:

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

我可以这样做吗:

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

?

【问题讨论】:

  • 除了 Yole 的回答之外,如果它的 memberproperties 方法不可用,只需在 build.gradile 文件实现 'org.jetbrains.kotlin:kotlin-reflect:1.5.10' 中引入这个库跨度>

标签: kotlin


【解决方案1】:

首先,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)}")
    }  
}

【讨论】:

  • 您需要检查每个属性并将其转换为 KProperty1 以调用 getter
  • 这仍然是最新的吗?得到一个没有属性 memberProperties 的错误
  • 更新了 API 链接。您需要将 kotlin-reflect 添加到依赖项中才能使用此方法。
  • @AdamHughes:添加此导入行:import kotlin.reflect.full.memberProperties
  • 我无法导入这个,可能是 kotlin 的旧版本。
【解决方案2】:

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

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")

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      这是一个想法……我对此并不满意……但它仍然存在。

      它有一些优点和缺点:

      • 优点:
        • 类型安全/编译时检查
          • 在数据类中添加/删除字段会导致字段迭代站点出现编译器错误
        • 不需要样板代码
      • 缺点:
        • 如果为参数定义了默认值将不起作用

      声明:

      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
          }
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-22
        • 1970-01-01
        • 2017-10-17
        • 2014-07-11
        • 2017-03-29
        • 2019-02-27
        • 2017-07-30
        • 2017-08-06
        相关资源
        最近更新 更多