Pointers Kotlin函数参数:无法重新分配Val

Pointers Kotlin函数参数:无法重新分配Val,pointers,kotlin,var,Pointers,Kotlin,Var,我在科特林写了红黑树。Fun insertFixup在插入新元素后恢复平衡(z:Node?是新元素)。树平衡算法取自(第2-3页)。问题是Kotlin不允许我将z重新分配给z.parent和z.parent.parent。我希望z是一个指针。问题是如何让科特林明白我想从他那里得到什么 class Node(key: Int) {...} class BinarySearchTree { var root: Node? = null fun insert(newNode: No

我在科特林写了红黑树。Fun insertFixup在插入新元素后恢复平衡(z:Node?是新元素)。树平衡算法取自(第2-3页)。问题是Kotlin不允许我将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)
    }
}
类节点(键:Int){…}
类二进制搜索树{
变量根:节点?=null
有趣的插入(newNode:Node){…}
fun RotateLeft(x:Node?{…}
有趣的旋转光(x:Node?{…}
有趣的insertFixup(z:Node?){
变量y:节点?
而(z?.parent?.color==“红色”){
如果(z?.parent==z?.parent?.parent?.left){
y=z?父母?父母?对吗
如果(y?.color==“红色”){
z?.parent?.color=“黑色”
y?.color=“黑色”
z?.parent?.parent?.color=“红色”
z=z?父?父
}
如果(z==z?.parent?.right){
z=z?父项
旋转英尺(z)
z?.parent?.color=“黑色”
z?.parent?.parent?.color=“红色”
旋转光(z?父?父)
}
}否则{
y=z?父?父?左
如果(y?.color==“红色”){
z?.parent?.color=“黑色”
y?.color=“黑色”
z?.parent?.parent?.color=“红色”
z=z?父?父
}
如果(z!=z?.parent?.left){
z=z?父项
旋转英尺(z)
z?.parent?.color=“黑色”
z?.parent?.parent?.color=“红色”
旋转光(z?父?父)
}
}
}
root?.color=“黑色”
}
}
趣味主线(args:Array){
val bst=BinarySearchTree()
while(true){
var newNode=Node(readLine()!!.toInt())
bst.insert(新节点)
bst.insertFixup(新节点)
}
}

UPD:谢谢大家!所有的答案都很有帮助,我在您的回复中找到了解决方案。

Kotlin中的函数参数基本上是函数内部的只读
val
,因此这里的
z
将始终引用传入的原始对象

如果在函数运行时需要修改它所指向的内容,则必须在函数开头制作它的本地副本,然后可以将其设置为
var

例如,您可以像这样启动函数,以便以后重新分配此本地
var

fun insertFixup(_z: Node?) {
    var z = _z
    // ...
    z = z.parent
    // ...
}

Kotlin函数参数为只读值,不可赋值

但是,您可以创建一个要传递给
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)
    }
}

我也遇到了这个问题。我所做的是创建一个数据类,并将该数据类作为参数传递,然后使用该参数修改其属性

data class SomeDataClass(
    val x: Int,
    val y: Int,
    val z: Int
)

fun someMethod(someDataClass: SomeDataClass) {
    someDataClass.z = 23 //whatever Int value you please
    // more computations...
    someDataClass.z = 67 // or whatever new value you need to assign.
}

fun parentMethod() {
    val someDataClass = SomeDataClass()
    someMethod(someDataClass)
    val newZValue = someDataClass.z // someDataClass holds modified data from above 
                                    // method
}

在我的例子中,我正在为不同的应用程序管理数据的内容提供者工作。我得到了一个新的kotlin文件,该文件继承了来自内容提供商的属性,如下所示:

类ProviderClass():ContentProvider(){

}

ContentProvider()是一个抽象类,因此我们需要实现所有成员

我试图将值重新分配给sortOrder参数,在那个参数上我遇到了这些问题。 我要解决的是, //实施成员后

....
override fun query(
        uri: Uri,
        projection: Array<out String>?,
        selection: String?,
        selectionArgs: Array<out String>?,
        sortOrder: String?
    ): Cursor? {
var _sortOrder = sortOrder
if (sortOrder == null || sortOrder == ""){
            _sortOrder = NAME
        }
val cursor = qb.query(db, projection, selection, selectionArgs, null, null, _sortOrder) //_sorOrder newly created variable

。。。。
覆盖有趣的查询(
uri:uri,
投影:数组?,
选择:字符串?,
SelectionAgs:数组?,
排序器:字符串?
):光标?{
var\u sortOrder=sortOrder
if(sortOrder==null | | sortOrder==“”){
_sortOrder=名称
}
val cursor=qb.query(db、projection、selection、selectionArgs、null、null、\u sortOrder)/\u sorOrder新创建的变量

我创建了一个名为_sortOrder的新变量,并将新创建的变量放在查询方法上,在第二个变量上有两个空值,我在其中创建了一个名为cursor的新变量,并将新创建的变量设置为我们想要设置的值。

这并没有回答如何使
z
类似指针的问题。我没有取消了解为什么要制作z的本地副本并使其变为var。即使按照您所说的那样制作z的本地副本,也无法重新分配到z。这不起作用。这个答案应该是错误的,或者请更正。问题是关于在函数内重新分配函数参数的值,例如
z=z.parent
。这是不可能的,但是如果你使用一个本地
var
,你可以根据你的喜好重新分配这个本地
var
。一个小提示:如果你检查
z
是否为
null
,或者在
insertFixup
的开头只检查一次,我认为你可以大大改进代码。现在到处都有太多
)问题是如何让Kotlin明白我想从他那里得到什么?lol:)在Java中,通过在参数前添加
final
关键字,函数参数可以变成只读的。Kotlin默认情况下会这样做
....
override fun query(
        uri: Uri,
        projection: Array<out String>?,
        selection: String?,
        selectionArgs: Array<out String>?,
        sortOrder: String?
    ): Cursor? {
var _sortOrder = sortOrder
if (sortOrder == null || sortOrder == ""){
            _sortOrder = NAME
        }
val cursor = qb.query(db, projection, selection, selectionArgs, null, null, _sortOrder) //_sorOrder newly created variable