如何在kotlin中动态遍历类的所有字段

  • 本文关键字:字段 遍历 动态 kotlin kotlin
  • 更新时间 :
  • 英文 :


我想动态遍历kotlin中一个类的所有字段。目的是通过连接所有字段将类对象转换为TSV。由于会有很多子类,所以动态地这样做会很好。经过一番调查,我在下面找到了一个解决方案。它确实起了作用,但字段的顺序与每个字段的声明顺序不一致。

我认为注释可以工作,但不确定如何工作。知道吗?谢谢

abstract class BaseModel {
fun toTSV(): String {
return this::class.memberProperties.map {
it.getter.call(this).toString()
}.joinToString("t")
}
}
class Model (
val model_id: String,
val name: String,
val version: Int,
val desc: String
) : BaseModel()

fun main(args : Array<String>) {
val model = Model(
model_id = "mid",
name = "model name",
version = 1,
desc = "some desc"
)
println(model.toTSV())
}

上面的代码产生:

some_desc   mid model_name  1

但我期待:

mid  model_name  1   some_desc

就像类中字段的顺序一样。

使用泛型和扩展属性,我们可以像一样实现这一点

val <T> T.fields: List<String>
get() {
return this!!::class.java.declaredFields.map { it.name }
}
val <T> T.fieldsString: String
get() {
return this!!::class.java.declaredFields.map { it.name }.joinToString(", ")
}

fun toTSV2(): String {
val name2value = this::class.memberProperties.map {
it.name to it.getter.call(this).toString()
}.toMap()
return this!!::class.java.declaredFields.map { 
name2value[it.name] }.joinToString("t")
}

我建议您在每个模型上覆盖toString,以在每个字段中获得制表符分隔的值:(

class MyModel {
var id: Long = 0L
...
override fun toString(): String {
val sb = StringBuilder()
sb.append("class MyModel {n")
sb.append("    id: ").append(toIndentedString(id)).append("n")
sb.append("n}")
return sb.toString()
}

/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private fun toIndentedString(o: Any?): String {
return o?.toString()?.replace("n", "n    ") ?: "null"
}
}

这对我每次都有效。

好的,结合Brandon的回答,我终于得到了这个。成功了:

fun toTSV2(): String {
val name2value = this::class.memberProperties.map {
it.name to it.getter.call(this).toString()
}.toMap()
return this!!::class.java.declaredFields.map { 
name2value[it.name] }.joinToString("t")
}

最新更新