Kotlin,ArrayList的set方法不会替换给定的元素
我正在将子弹移植到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 = pa!! val pb = pb!! 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) } }
但是由于root0
是null
我马上就会退出。 在下一次我输入函数时, root0
和root1
都是有效的对象,它们的引用如下:
root0 = Dbvt@708 root1 = Dbvt@656
然后我创建第一个添加到stkStack
元素,它仍然是空的,定义如下:
val stkStack = ArrayList()
element
是如此定义的StkNN
类:
class StkNN(var a: DbvtNode? = null, var b: DbvtNode? = null)
插入后,我得到:
这是有道理的。
stkStack resize DOUBLE_STACKSIZE
只需创建一些虚拟的StkNN实例
然后我输入do
,然后抓住stkStack
的第一个元素,这基本上就是我们刚刚插入的元素:
p = {Dbvt$StkNN@731} a = {DbvtNode@708} b = {DbvtNode@656}
然后,我们跳过下一个, if
我保存variablespa
和pb
作为不可变的检查可空性
val pa = pa!! val pb = pb!!
pa
和pb
在引用方面是一致的:
pa = @708 pb = @656
现在我们直接在这里 :
} else { stkStack[depth++] = StkNN(pa.childs[0], pb) stkStack[depth++] = StkNN(pa.childs[1], pb) }
depth
现在是0
和stkStack
包含一个元素,我们插入在开始,所以它应该取代它与一个新的实例
那么, 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
指针实际上应该是,就是说,它对应于pa->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)
中的文档set(index: Int, element: Dbvt.stkNN)
,它说:
将此列表中指定位置的元素替换为指定的元素
但是,这不是什么情况
这是我的IDE /项目( 相关 )损坏的东西。 重新克隆项目解决了这个问题
特别感谢downvote&run家伙,这总是一种乐趣