Kotlin函数参数:Val不能被重新分配
我在科特林写过红黑树。 有趣的insertFixup在插入新元素( z:Node?是新元素)后恢复平衡。 从这里取得树木平衡的算法(2-3页)。 问题是Kotlin 不允许我重新分配 z.parent和z.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) { val bst = BinarySearchTree() while (true) { var newNode = Node(readLine()!!.toInt()) bst.insert(newNode) bst.insertFixup(newNode) } }
UPD:感谢所有! 所有的答案是有帮助的,我已经find了答案的解决方案。
Kotlin中的函数参数是函数内部的只读val
,所以在这里z
总是指传入的原始对象。
如果你需要在你的函数运行的时候修改它指向的内容,你必须在函数的开头创建一个本地副本,然后你可以创建一个var
。
例如,你可以像这样开始你的function:
fun insertFixup(_z: Node?) { var z = _z
Kotlin函数参数是只读值,不可分配。
然而你可以创建一个ReadWriteProperty
对象来传递给insertFixup
来获取/设置newNode
:
... class BinarySearchTree { ... fun insertFixup(zProperty: ReadWriteProperty) { var z by zProperty ... fun main(args: Array) { val bst = BinarySearchTree() var newNode: Node? = null val newNodeProperty = object : ReadWriteProperty { 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) } }
如果您愿意使用属性而不是variables,那么您可以使用属性引用来从insertFixup
获取/设置newNode
:
... class BinarySearchTree { ... fun insertFixup(zProperty: KMutableProperty0) { var z by zProperty ... var newNode: Node? = null fun main(args: Array) { 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 KProperty0 .getValue(thisRef: Any?, property: KProperty<*>): T = get() operator fun KMutableProperty0 .setValue(thisRef: Any?, property: KProperty<*>, value: T) = set(value)
- Dagger2不能在andorid中工作
- 为什么在OnFocusChangeListener中调用setText()会清除视图中的文本?
- 如何为Kotlin和Gradle设置“sourceCompatibility”?
- Spring REST,Kotin和默认的基本参数导致错误
- 我怎样才能把KFunction没有实例参数的KFunction?
- 在使用arrayOfNulls时,是否可以删除Kotlin中未经检查的转换?
- “包含Kotlin支持”复选框不在Android Studio 3.0 Canary 5中
- DataBinding不能用在我在Kotlin编码的BaseActivity中
- ListView可以出现在Activity中,但不能出现在Fragment中