Kotlin,ArrayList set方法没有用给定的

时间:2018-02-01 10:29:38

标签: reference kotlin

我将bullet移植到kotlin并编写了运行HelloWorld示例所需的所有内容。

我现在处于调试阶段,我遇到了对象引用问题。

一开始,我第一次输入collideTTpersistentStack

fun collideTTpersistentStack(root0: DbvtNode?, root1: DbvtNode?, collider: DbvtTreeCollider) {
    if (root0 != null && root1 != null) {
        var depth = 1
        var treshold = DOUBLE_STACKSIZE - 4

        val element = StkNN(root0, root1)
        if (stkStack.isNotEmpty()) stkStack[0] = element
        else stkStack += element
        stkStack resize DOUBLE_STACKSIZE
        do {
            val p = stkStack[--depth]
            if (depth > treshold) {
                stkStack resize (stkStack.size * 2)
                treshold = stkStack.size - 4
            }
            val pa = p.a!!
            val pb = p.b!!
            if (pa === pb) {
                if (pa.isInternal) {
                    stkStack[depth++] = StkNN(pa.childs[0], pa.childs[0])
                    stkStack[depth++] = StkNN(pa.childs[1], pa.childs[1])
                    stkStack[depth++] = StkNN(pa.childs[0], pa.childs[1])
                }
            } else if (pa.volume intersect pb.volume)
                if (pa.isInternal)
                    if (pb.isInternal) {
                        stkStack[depth++] = StkNN(pa.childs[0], pb.childs[0])
                        stkStack[depth++] = StkNN(pa.childs[1], pb.childs[0])
                        stkStack[depth++] = StkNN(pa.childs[0], pb.childs[1])
                        stkStack[depth++] = StkNN(pa.childs[1], pb.childs[1])
                    } else {
                        stkStack[depth++] = StkNN(pa.childs[0], pb)
                        stkStack[depth++] = StkNN(pa.childs[1], pb)
                    }
                else
                    if (pb.isInternal) {
                        stkStack[depth++] = StkNN(pa, pb.childs[0])
                        stkStack[depth++] = StkNN(pa, pb.childs[1])
                    } else
                        collider.process(pa, pb)
        } while (depth != 0)
    }
}

但由于root0null,我立即退出。下次我输入函数时,root0root1都是有效对象,其引用如下:

root0 = Dbvt@708
root1 = Dbvt@656

然后我创建了第一个要添加到stkStack的元素,它仍然是空的,定义为:

val stkStack = ArrayList<StkNN>()

element是如此定义的StkNN类:

class StkNN(var a: DbvtNode? = null, var b: DbvtNode? = null)

插入后,我得到:

enter image description here

这是有道理的。

stkStack resize DOUBLE_STACKSIZE只需创建一些虚拟StkNN实例

然后我输入do并抓住stkStack上的第一个元素,它基本上就是我们刚插入的元素:

p = {Dbvt$StkNN@731}
   a = {DbvtNode@708}
   b = {DbvtNode@656}

然后我们跳过下一个if,我将变量p.ap.b保存为对可空性的不可变检查

val pa = p.a!!
val pb = p.b!!

papb在引用方面都是一致的:

pa = @708
pb = @656

现在我们直接降落here

} else {
    stkStack[depth++] = StkNN(pa.childs[0], pb)
    stkStack[depth++] = StkNN(pa.childs[1], pb)
}

depth现在是0stkStack包含一个元素,即我们在开头插入的元素,因此它应该用新实例替换它

嗯,pa孩子是以下

pa = {DbvtNode@708} 
 childs = {DbvtNode[2]@748} 
  0 = {DbvtNode@759} 
  1 = {DbvtNode@656} 

但在跳过作业后,stkStack将包含以下内容:

stkStack = {ArrayList@709}  size = 128
 0 = {Dbvt$StkNN@772} 
  a = {DbvtNode@708} // this is wrong, it should be @759
  b = {DbvtNode@656} 
 1 = {Dbvt$StkNN@781} 
  a = {DbvtNode@656} // right
  b = {DbvtNode@656} // right

C ++代码使用指针,我仔细检查执行,它的stkStack[0].a指针实际上是应该的,也就是说,它对应于p.a->childs[0]指针

发生了什么事?

编辑:如果我在添加实例之前创建虚拟对象:

val test = StkNN(pa.childs[0], pb)
stkStack[depth++] = StkNN(pa.childs[0], pb)
stkStack[depth++] = StkNN(pa.childs[1], pb)

它确实有正确的引用,test.a实际上是pa.childs[0]。如果我直接指定test

val test = StkNN(pa.childs[0], pb)
stkStack[depth++] = test
stkStack[depth++] = StkNN(pa.childs[1], pb)

stkStack[0] test ..! 查看set(index: Int, element: Dbvt.stkNN)中的文档,它说:

  

使用指定的元素

替换此列表中指定位置的元素

但这不是发生的事情

1 个答案:

答案 0 :(得分:1)

我的IDE /项目(related)中存在损坏的内容。重新克隆项目解决了问题

特别感谢downvote&amp; run guys,它总是很愉快