Kotlin函数参数:Val不能被重新分配

我在科特林写过红黑树。 有趣的insertFixup在插入新元素( z:Node?是新元素)后恢复平衡。 从这里取得树木平衡的算法(2-3页)。 问题是Kotlin 不允许我重新分配 z.parentz.parent.parent 。 我想z是一个指针 。 问题是如何让Kotlin明白我想从他那里得到什么?

class Node(key: Int) {...} class BinarySearchTree { var root: Node? = null fun insert(newNode: Node) {...} fun RotateLeft(x: Node?) {...} fun RotateRight(x: Node?) {...} fun insertFixup(z: Node?) { var y: Node? while (z?.parent?.color == "RED") { if (z?.parent == z?.parent?.parent?.left) { y = z?.parent?.parent?.right if (y?.color == "RED") { z?.parent?.color = "BLACK" y?.color = "BLACK" z?.parent?.parent?.color = "RED" z = z?.parent?.parent } if (z == z?.parent?.right) { z = z?.parent RotateLeft(z) z?.parent?.color = "BLACK" z?.parent?.parent?.color = "RED" RotateRight(z?.parent?.parent) } } else { y = z?.parent?.parent?.left if (y?.color == "RED") { z?.parent?.color = "BLACK" y?.color = "BLACK" z?.parent?.parent?.color = "RED" z = z?.parent?.parent } if (z != z?.parent?.left) { z = z?.parent RotateLeft(z) z?.parent?.color = "BLACK" z?.parent?.parent?.color = "RED" RotateRight(z?.parent?.parent) } } } root?.color = "BLACK" } } fun main(args: Array<String>) { val bst = BinarySearchTree() while (true) { var newNode = Node(readLine()!!.toInt()) bst.insert(newNode) bst.insertFixup(newNode) } } 

UPD:感谢所有! 所有的答案是有帮助的,我已经找到了答案的解决方案。

Kotlin中的函数参数是函数内部的只读val ,所以在这里z总是会引用传入的原始对象。

如果你需要在你的函数运行的时候修改它指向的内容,你必须在函数的开头创建一个本地副本,然后你可以创建一个变量。

例如,你可以像这样开始你的功能:

 fun insertFixup(_z: Node?) { var z = _z 

Kotlin函数参数是只读值,不可分配。

然而你可以创建一个ReadWriteProperty对象来传递给insertFixup来获取/设置newNode

 ... class BinarySearchTree { ... fun insertFixup(zProperty: ReadWriteProperty<Any?, Node?>) { var z by zProperty ... fun main(args: Array<String>) { val bst = BinarySearchTree() var newNode: Node? = null val newNodeProperty = object : ReadWriteProperty<Any?, Node?> { override operator fun getValue(thisRef: Any?, property: KProperty<*>): Node? { return newNode } override operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Node?) { newNode = value } } while (true) { newNode = Node(readLine()!!.toInt()) bst.insert(newNode!!) bst.insertFixup(newNodeProperty) } } 

如果您愿意使用属性而不是变量,那么您可以使用属性引用来从insertFixup获取/设置newNode

 ... class BinarySearchTree { ... fun insertFixup(zProperty: KMutableProperty0<Node?>) { var z by zProperty ... var newNode: Node? = null fun main(args: Array<String>) { val bst = BinarySearchTree() while (true) { newNode = Node(readLine()!!.toInt()) bst.insert(newNode!!) bst.insertFixup(::newNode) } } // the following allow `KMutableProperty0` to be used as a read/write delegate operator fun <T> KProperty0<T>.getValue(thisRef: Any?, property: KProperty<*>): T = get() operator fun <T> KMutableProperty0<T>.setValue(thisRef: Any?, property: KProperty<*>, value: T) = set(value) 
Interesting Posts