首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin函数参数:无法重新分配Val

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

Stack Overflow用户
提问于 2017-03-01 19:09:41
回答 4查看 64.5K关注 0票数 44

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

代码语言:javascript
复制
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:感谢大家!所有的答案都很有帮助,我在你的答复中找到了解决办法。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-03-01 19:25:23

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

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

例如,您可以像这样启动您的函数,它允许您稍后重新分配这个本地var

代码语言:javascript
复制
fun insertFixup(_z: Node?) {
    var z = _z
    // ...
    z = z.parent
    // ...
}
票数 64
EN

Stack Overflow用户

发布于 2017-03-01 20:06:56

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

但是,您可以创建一个ReadWriteProperty对象,以传递给insertFixup以获取/设置newNode

代码语言:javascript
复制
...
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

代码语言:javascript
复制
...
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)
票数 8
EN

Stack Overflow用户

发布于 2019-10-09 18:45:31

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

代码语言:javascript
复制
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
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42540035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档