gpt4 book ai didi

android - Kotlin:lateinit 到 val,或者,可以设置一次的 var

转载 作者:IT老高 更新时间:2023-10-28 13:31:19 28 4
gpt4 key购买 nike

只是好奇:在 Kotlin 中,我很想得到一些可以由惰性初始化但带有参数的 val。那是因为我需要一些很晚才创建的东西来初始化它。

具体来说,我希望我有:

private lateinit val controlObj:SomeView

或:

private val controlObj:SomeView by lazy { view:View->view.findViewById(...)}

然后:

override fun onCreateView(....) {
val view = inflate(....)


controlObj = view.findViewById(...)

或在第二种情况下 controlObj.initWith(view) 或类似的东西:

return view

我不能使用 by lazy 因为 by lazy 在初始化时不接受要使用的外部参数。在这个例子中 - 包含 view.

当然我有 lateinit var 但是如果我能确保它在设置后变为只读并且我可以在一行中完成它会很好。

是否有一种非常简洁的方法来创建一个只读变量,该变量只初始化一次,但只有在其他一些变量产生时才初始化?任何 init once 关键字?在init之后编译器知道它是不可变的吗?

我知道这里潜在的并发问题,但如果我敢在初始化之前访问它,我当然应该被扔掉

最佳答案

你可以像这样实现自己的委托(delegate):

class InitOnceProperty<T> : ReadWriteProperty<Any, T> {

private object EMPTY

private var value: Any? = EMPTY

override fun getValue(thisRef: Any, property: KProperty<*>): T {
if (value == EMPTY) {
throw IllegalStateException("Value isn't initialized")
} else {
return value as T
}
}

override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
if (this.value != EMPTY) {
throw IllegalStateException("Value is initialized")
}
this.value = value
}
}

之后你可以如下使用它:

inline fun <reified T> initOnce(): ReadWriteProperty<Any, T> = InitOnceProperty()

class Test {

var property: String by initOnce()

fun readValueFailure() {
val data = property //Value isn't initialized, exception is thrown
}

fun writeValueTwice() {
property = "Test1"
property = "Test2" //Exception is thrown, value already initalized
}

fun readWriteCorrect() {
property = "Test"
val data1 = property
val data2 = property //Exception isn't thrown, everything is correct
}

}

如果您在初始化之前尝试访问值,您将得到异常以及尝试重新分配新值时。

关于android - Kotlin:lateinit 到 val,或者,可以设置一次的 var,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48443167/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com