我對不同的行為感到困惑,這取決于我是使用 getter 還是委托屬性。考慮以下:
class Test {
class Parts(val a: String, val b: String)
var raw = ""
private var cachedParts: Parts? = null
val parts: Parts
get() {
println("@2")
return cachedParts
?: raw.split("/")
.let { Parts(it.getOrElse(0) { "" }, it.getOrElse(1) { "" }) }
.also { cachedParts = it }
}
// WITH GETTERS:
val partA get() = parts.a
val partB get() = parts.b
}
fun main() {
val t = Test()
println("@1")
t.raw = "one/two"
println("a=${t.partA}, b=${t.partB}")
}
此代碼raw在第一次parts訪問時將字串分成兩部分。以后的所有呼叫都parts將回傳快取的部分,即使raw發生更改。輸出:
@1
@2
@2
a=one, b=two
的值raw在Test創建時為空,但在我們設定raw為某個字串之前不會呼叫訪問器。當partA和partB最終被訪問時,它們包含正確的值。
如果我改用屬性委托,則代碼不再有效:
class Test {
class Parts(val a: String, val b: String)
var raw = ""
private var cachedParts: Parts? = null
val parts: Parts
get() {
println("@2")
return cachedParts
?: raw.split("/")
.let { Parts(it.getOrElse(0) { "" }, it.getOrElse(1) { "" }) }
.also { cachedParts = it }
}
// WITH DELEGATION:
val partA by parts::a
val partB by parts::b
}
fun main() {
val t = Test()
println("@1")
t.raw = "one/two"
println("a=${t.partA}, b=${t.partB}")
}
我在這里所做的partA只是現在委托給parts::a,對于partB. 出于某種奇怪的原因,partA并且partB現在在設定值之前訪問raw,所以cachedParts用兩個空部分初始化。輸出:
@2
@2
@1
a=, b=
有人可以解釋這里發生了什么嗎?
uj5u.com熱心網友回復:
在此處的檔案中查看您的委托屬性轉換為什么。例如,partA轉換為:
private val partADelegate = parts::a
val partA: String
get() = partADelegate.getValue(this, this::partA)
請注意,可呼叫參考運算式part::a用于初始化partADelegate. 此運算式在Test創建的實體時計算, before println("@1")。
要評估parts::a,parts必須先評估。畢竟,這是對 的a屬性的parts參考,而不是對 的參考parts。
因此,parts最終在raw獲得其價值之前被評估。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/408071.html
標籤:
上一篇:更改視圖在android中的位置
