Kotlin 一个属性,一旦赋值为none null值,它将从var更改为val?

Kotlin 一个属性,一旦赋值为none null值,它将从var更改为val?,kotlin,Kotlin,如果Kotlin将添加一个属性,该属性一旦被赋值为none null值,var属性将被更改为val,这意味着您不能再更改该值,这是否有用 val? context Context? = null ... ... ... context = this ... ... ... context = this.applicationContext //would be an error since context //is val

如果Kotlin将添加一个属性,该属性一旦被赋值为none null值,var属性将被更改为val,这意味着您不能再更改该值,这是否有用

val? context Context? = null
...
...
...
context = this
...
...
...
context = this.applicationContext //would be an error since context   
                                  //is val 

以上只是一个例子,说明它是多么有用……

我认为这可能是您在这种情况下真正想要的:

val context:Context by lazy { this }

这已经是可能的:

fun test() {
  val s : String

  println(s) // Error: Variable 's' must be initialized

  s = "Hello"
  println(s)

  s = "World!" // Error: Val cannot be reassigned
}
否则,就没有可能做到这一点。例如,如果希望将其作为成员属性,编译器可能无法知道之前是否调用过方法以及是否允许赋值


@ligi的答案是一个很好的选择。

所有具有“特殊”行为的属性都可以使用

所有功能请求都应该通过。事实上,已经有人要求你的建议了

以下是一个可能的实施方案(来自问题):


我指的是一个属性,而不是函数中的变量。属性总是要求初始化。
class InitOnceVar<T>() : ReadWriteProperty<Any?, T> {
    private var initialized = false
    private var value: T? = null

    override fun get(thisRef: Any?, desc: PropertyMetadata): T {
        if (!initialized) throw IllegalStateException("Property ${desc.name} should be initialized before get")
        return value
    }

    override fun set(thisRef: Any?, desc: PropertyMetadata, value: T) {
        if (initialized) throw IllegalStateException("Property ${desc.name} could be initialized only once")
        this.value = value
        initialized = false
    }
}
var x: String by InitOnceVar()
x = "star"
x = "stop"  //Exception