【问题标题】:How to collect members via reflection to pass as argument later如何通过反射收集成员以稍后作为参数传递
【发布时间】:2018-05-01 20:16:00
【问题描述】:

因此,我正在研究一个概念,该概念涉及自动写入 ByteBuffer 扩展 Bufferizable 的类的内容

abstract class Bufferizable {

    abstract val fieldOrder: Array<String>

    open fun size(): Int = TODO()

    var initialized = false

    open infix fun to(address: Long) {

        if (initialized) {

            addFunctions.forEach {  }

        } else {

            addFunctions = Array(fieldOrder.size) { null }
            members = Array(fieldOrder.size) { null }

            fieldOrder.forEachIndexed { i, field ->
                val member = this::class.declaredMemberProperties.find { it.name == field }!!
                addFunctions[i] = when (member.returnType) {
                    Mat4::class.defaultType.javaType -> WithAddress::addMat4
                    ...
                    else -> throw Error()
                } as BufferizableAddFunctionType
                members[i] = member.get(this) // error
            }

            initialized = true
        }
    }

    infix fun from(address: Long): Unit = TODO()

    var addFunctions = arrayOf<BufferizableAddFunctionType?>()
    var members = arrayOf<Any?>()
}

typealias BufferizableAddFunctionType = (Any) -> Unit

object WithAddress {

    var address = NULL
    var offset = 0

    fun addMat4(mat4: Mat4) {
        for (i in 0..3)
            for (j in 0..3) {
                memPutFloat(address + offset, mat4[i, j])
                offset += Float.BYTES
            }
    }
    ...
}

这个想法是声明,例如,以下

object uboVS : Bufferizable() {

    var projectionMatrix = Mat4()
    var modelMatrix = Mat4()
    ...

    override val fieldOrder = arrayOf("projectionMatrix", "modelMatrix", "viewMatrix")
}

然后每当uboVS to address第一次被调用时,它将被初始化,然后按照指定的顺序将其内容写入本机地址。

但我唯一遇到的问题是收集成员以稍后作为参数传递给第 i 个addFunction

因为编译器在这里抱怨:

members[i] = member.get(this)

错误:(328, 37) Kotlin: Out-projected type 'KProperty1' 禁止使用 'public abstract fun get(receiver: T): R defined in kotlin.reflect.KProperty1'

我该如何解决?

【问题讨论】:

    标签: reflection kotlin kotlin-reflect


    【解决方案1】:

    这是一个继承问题。你的反射调用 this::class.declaredMemberProperties.find{ ... } 返回一个 KProperty1&lt;out Bufferizable, Any?&gt; 这意味着一个从 Bufferizable 继承的属性(有关 out 的更多信息,请参阅 declaration-site variance)。通过编译器不知道该属性属于哪个类,它不允许直接访问。要解决这个问题,您必须访问 getter 函数:

    members[i] = member.getter.call(this)
    

    通过getter函数属于对象而不属于反射api,它遵循默认的继承行为,可以被调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      • 1970-01-01
      • 2020-12-20
      相关资源
      最近更新 更多