Writing a Kotlin util function which provides self-reference in initializer

前端 未结 3 1954
广开言路
广开言路 2020-12-06 06:05

I\'m trying to generalize my hack from an answer to another question.

It should provide a way to reference a value which is not constructed yet inside its initializ

3条回答
  •  旧时难觅i
    2020-12-06 06:51

    is there a way to rewrite SelfReference so that initializer is passed an argument (or a receiver) instead of using self property? This question can be reformulated to: is there a way to pass a lazily evaluated receiver/argument to a function or achieve this semantics some way?

    I'm not sure I completely understand your use case but this may be what you're looking for:

    fun initHolder(x: Int = 0, holderAction: Holder.() -> Unit) : Holder {
        var h: Holder? = null
        h = Holder(x) { h!!.holderAction() }
        return h
    }
    
    val h: Holder = initHolder(0) { x++ }
    h.action()
    h.action()
    println(h.x) // 2
    

    This works because holderAction is a lambda with a receiver (Holder.() -> Unit) giving the lambda access to the receiver's members.

    This is a general solution since you may not be able to change the signature of the respective Holder constructor. It may be worth noting this solution does not require the class to be open, otherwise a similar approach could be done with a subclass using a secondary constructor.

    I prefer this solution to creating a SelfReference class when there are only a few number of classes that need the change.

    You may want to check for null instead of using !! in order to throw a helpful error. If Holder calls action in it's constructor or init block, you'll get a null pointer exception.

提交回复
热议问题