私はハックを別の答えquestionに一般化しようとしています。イニシャライザで自己参照を提供するKotlinのutil関数を書く
初期化子の内部ではまだ構築されていない値を参照する方法を提供するはずです(もちろん、直接ではなく、ラムダとオブジェクト式で)。
私が現時点で持っている:
class SelfReference<T>(val initializer: SelfReference<T>.() -> T) {
val self: T by lazy {
inner ?: throw IllegalStateException("Do not use `self` until initialized.")
}
private val inner = initializer()
}
fun <T> selfReference(initializer: SelfReference<T>.() -> T): T {
return SelfReference(initializer).self
}
それは動作しますが、この例を参照してください。
class Holder(var x: Int = 0,
val action:() -> Unit)
val h: Holder = selfReference { Holder(0) { self.x++ } }
h.action()
h.action()
println(h.x) //2
しかし、この時点でinitializer
が構築された値を参照する方法はself
プロパティです。
私の質問は、initializer
にself
プロパティを使用する代わりに引数(または受信者)が渡されるようにSelfReference
を書き換える方法はありますか?この質問は、遅延評価された受信側/引数を関数に渡すか、このセマンティクスを何らかの方法で達成する方法があるか、
コードを改善する他の方法は何ですか?
UPD:可能な方法の1つは、
self
を返す関数を渡すことです。したがって、
initializer
の内部に
it()
として使用されます。まだ他のものを探しています。
[委任されたプロパティ](https://kotlinlang.org/docs/reference/delegated-properties.html#delegated-properties)、[late-initialized properties](https: /kotlinlang.org/docs/reference/properties.html#late-initialized-properties)、[インライン関数](https://kotlinlang.org/docs/reference/inline-functions.html#inline-functions)これを一般化する。私の試みはうまくいくはずですが、Kotlinのコンパイルのバグがありました(https://youtrack.jetbrains.com/issue/KT-10878を参照)。 – mfulton26