懒惰variables与重置

我想创建一个非空的某种types的variables,比如说Foo。

然后,我想要所有访问variables返回Foo,就像一个懒惰的委托,但是,我也希望能够重置它。

就像是:

var foo : String by Foo(init: {"bar"}) print(foo) // prints "bar" foo = null // or foo.reset() print(foo) // prints "bar" 

我想解决的问题:我有一个适配器的索引,我需要在适配器内容更改时重新创建。 所以在变化我想清除索引,并在下一次有人试图访问它,我想重新创建它。

如果目标是有一个可以重置为初始状态的惰性初始化var property ,则可以使Kotlin的SynchronizedLazyImpl允许无效特性:

 private object UNINITIALIZED_VALUE class InvalidatableLazyImpl(private val initializer: () -> T, lock: Any? = null) : Lazy, Serializable { @Volatile private var _value: Any? = UNINITIALIZED_VALUE private val lock = lock ?: this fun invalidate(){ _value = UNINITIALIZED_VALUE } override val value: T get() { val _v1 = _value if (_v1 !== UNINITIALIZED_VALUE) { return _v1 as T } return synchronized(lock) { val _v2 = _value if (_v2 !== UNINITIALIZED_VALUE) { _v2 as T } else { val typedValue = initializer() _value = typedValue typedValue } } } override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet." operator fun setValue(any: Any, property: KProperty<*>, t: T) { _value = t } } 

然后可以如下使用:

 private val fooDelegate = InvalidatableLazyImpl({"bar"}) var foo:String by fooDelegate println(foo); // -> "bar" foo = "updated" println(foo); // -> "updated" fooDelegate.invalidate() println(foo); // -> "bar" 

人们可以明显地修改委托实现,以允许null值作为重置,但它可以使代码难以推理,即:

 println(obj.foo); //-> prints "bar obj.foo = null //reset the value, implicitely println(obj.foo); //-> prints "bar", but hey didn't I just said `null`