Kotlin:将函数中的对象作为引用传递并更改其实例

时间:2017-10-19 08:35:40

标签: android kotlin

我找不到如何传递对象的引用,以便我可以让它们指向内存中的新位置。 如何在Kotlin做到这一点?

代码:

class Parent {

}

class Child : Parent {

}

class GlobalDataHolder {

    var globalChildVriable: Child? = null // imagine this is a static variable and can be accessed anywhere
}

class Activity() {
    var variable1 = Child()

    Helper.init(variable1, GlobalDataHolder.globalChildVriable) // inside onCreate()

}

class Helper {

    initStuff(variable1: Parent, globalVariable: Parent?) {
        if (globalVariable == null) {
             globalVariable = variable1 // error saying val cannot be re-assigned
        }
        else {
            variable1 = globalVariable!!
        }

    }
}

我希望variable1和globalVariable可以修改。 因此,他们的原始所有者将拥有最新的价值。

2 个答案:

答案 0 :(得分:1)

Kotlin(和Java)本身不支持像C / C ++这样的引用类型。 但是,kotlin确实具有属性和功能类型 属性基本上只是两个函数(getter和setter)的组合。您可以将属性作为参数传递,并使用反射从不同的上下文中单独调用其getter setter。

更新(可编译)代码:

open class Parent { }

open class Child : Parent() { }


var globalVariable: Child? = null


class Activity() {

    var localVariable = Child()

    init {
        Helper.initStuff(this::localVariable, ::globalVariable)
    }

}

object Helper {

    fun initStuff(localProperty: KMutableProperty0<out Parent>, globalProperty: KMutableProperty0<out Parent?>) {
        val globalVariable = globalProperty.call()
        val variable1 = localProperty.call()

        if (globalVariable == null) {
            globalProperty.setter.call(variable1)
        }
        else {
            variableProperty.setter.call(globalVariable)
        }

    }
}

答案 1 :(得分:0)

通过引入一个更多层次的抽象,可以“始终”解决这些问题。例如,您可以添加一个新的interface VarHolder,它负责获取/设置包含的变量。

interface VarHandle<E> {
    var variable: E
}
class Activity() {
    var variable1 = Child()

    fun onCreate() {
        Helper.initStuff(object : VarHandle<Child> {
            override var variable: Child
                get() = variable1
                set(value) { variable1 = value }

        }, object : VarHandle<Child?> {
            override var variable: Child?
                get() = GlobalDataHolder.globalChildVariable
                set(value) { GlobalDataHolder.globalChildVariable = value }
        })
    }
}

object Helper {

    fun initStuff(localVarHolder: VarHandle<Child>, globalVarHolder: VarHandle<Child?>) {
        val globalVar = globalVarHolder.variable
        val localVar = localVarHolder.variable

        if (globalVar == null) {
            globalVarHolder.variable = localVar
        }
        else {
            localVarHolder.variable = globalVar
        }

    }
}