Параметр функции Kotlin: Val не может быть переназначен

Я написал красно-черное дерево в Котлине. Fun insertFixup восстанавливает баланс после вставки нового элемента ( z: Node? Новый элемент). Отсюда берётся алгоритм балансировки деревьев (стр. 2-3). Проблема в том, что Котлин не позволяет переназначить z на z.parent и z.parent.parent . Я хочу, чтобы z был указателем . Вопрос в том, как заставить Котлина понять, чего я хочу от него?

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 являются постоянными значениями только для чтения внутри функции, поэтому z здесь всегда будет ссылаться на исходный объект, который был передан.

    Если вам нужно изменить то, на что указывает, пока ваша функция запущена, вам нужно будет сделать локальную копию в начале функции, а затем вы можете сделать это var .

    Например, вы можете запустить свою функцию следующим образом:

     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) } } 

    И если вы хотите использовать свойство вместо переменной, вы можете использовать ссылку на свойство для получения / установки newNode из insertFixup :

     ... 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)