【发布时间】:2016-01-30 10:04:01
【问题描述】:
我正在尝试将我的技巧从另一个question 的答案中概括出来。
它应该提供一种方法来引用尚未在其初始化程序中构造的值(当然,不是直接,而是在 lambdas 和对象表达式中)。
我现在拥有的:
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属性。
我的问题是:有没有办法重写 SelfReference 以便 initializer 被传递一个参数(或接收器)而不是使用 self 属性?这个问题可以重新表述为:有没有办法将延迟评估的接收器/参数传递给函数或以某种方式实现这种语义?
还有哪些其他改进代码的方法?
UPD: 一种可能的方法是传递一个返回
self 的函数,因此它将在initializer 中用作it()。还在寻找其他的。
【问题讨论】:
-
您可以使用delegated properties、late-initialized properties 和/或inline functions 的组合来概括这一点。我的尝试应该(我认为)有效,但有一个 Kotlin 编译错误阻止它现在这样做(请参阅youtrack.jetbrains.com/issue/KT-10878)。
标签: initialization this lazy-evaluation kotlin