Kotlin var lazy init

我想为一个var属性做一个懒惰的初始化。 由于by lazy只限于val属性,我必须写这样的东西:

  private var currentContextProvider: ContextProvider? = null get() { if (field == null) { field = DefaultContextProvider() } return field } 

现在我必须处理那些毫无意义的可currentContextProvider?.getContext()知的调用: currentContextProvider?.getContext()或者currentContextProvider!!.getContext()

难道我做错了什么?

您可以决定使用一些默认值来初始化它,而不是将它初始化为第一次访问时,它将被延迟计算的值替换:

 private val noInit = "noinit" var currentContextProvider: String = noInit get() = if (field == noInit) { synchronized(this) { return if (field == noInit) "lazyinit" else field } } else field 

(我已经用String替换了ContextProvider

自定义委托

以下实现一个自定义委托重用以前的解决方案。 通过定义var currentContextProvider: ContextProvider by LazyMutable(){DefaultContextProvider()}它可以像lazy()一样使用var currentContextProvider: ContextProvider by LazyMutable(){DefaultContextProvider()}

 class LazyMutable(val initializer: () -> T) : ReadWriteProperty { private object UNINITIALIZED_VALUE private var prop: Any? = UNINITIALIZED_VALUE @Suppress("UNCHECKED_CAST") override fun getValue(thisRef: Any?, property: KProperty<*>): T { return if (prop == UNINITIALIZED_VALUE) { synchronized(this) { return if (prop == UNINITIALIZED_VALUE) initializer().also { prop = it } else prop as T } } else prop as T } override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { synchronized(this) { prop = value } } }