我試圖觀察狀態,如你所見,但是當我使用when并嘗試獲取資料時,編譯器說Smart cast is impossible通過強制轉換解決了問題,但感覺就像我做錯了,我想知道還有其他解決方案來修復這個錯誤。
sealed class Response<out T : Any> {
object Loading : Response<Nothing>()
data class Success<out T : Any>(val data: T) : Response<T>()
data class Error(val error: ResultError, val message: String? = null) : Response<Nothing>()
}
val userState by userViewModel.userState.collectAsState()
when(userState){
is Response.Error -> userState.error // Smart cast to 'Response.Error' is impossible, because 'userState' is a property that has open or custom getter
Response.Loading -> Unit
is Response.Success -> userState.data // Smart cast to 'Response.Success<User>' is impossible, because 'userState' is a property that has open or custom getter
}
uj5u.com熱心網友回復:
這一行:
val userState by userViewModel.userState.collectAsState()
userState通過委托定義,所以編譯器不能保證 中的訪問when()和when的分支內的訪問將回傳相同的值。
您可以在此處使用中間變數:
val userState by userViewModel.userState.collectAsState()
when(val s = userState){
is Response.Error -> s.error
Response.Loading -> Unit
is Response.Success -> s.data
}
uj5u.com熱心網友回復:
編譯器只有在可以保證值不會隨時間變化的情況下才能執行智能轉換。否則,我們可能會遇到在型別檢查后變數更改為另一個值并且不再滿足先前約束的情況。
委托屬性(用by關鍵字宣告的)與“普通”變數有很大不同。它們實際上并沒有任何價值,但是每次我們訪問它們時,我們實際上是在它們的委托上呼叫getValue()(或setValue())。每次訪問時,委托人可能會提供不同的值。編譯器不能保證值的不變性,因此不允許智能轉換。
為了解決這個問題,我們需要創建一個被委托的資料的本地副本。這就像呼叫getValue()結果并將其存盤為區域變數一樣,因此無法再更改。然后我們可以對這個本地資料副本執行智能轉換。可以通過以下示例更好地理解:
fun main() {
val delegated by Delegate()
println(delegated) // 0
println(delegated) // 1
println(delegated) // 2
val local = delegated // `local` set to 3
println(local) // 3
println(delegated) // 4
println(local) // 3
}
class Delegate {
var i = 0
operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
return i
}
}
每次我們訪問delegated它都會回傳一個不同的值。它可能會在null與非空之間更改,甚至可以完全更改型別。當我們將它分配給local我們時,我們取“當前”值delegated并將其副本存盤在本地。然后delegated仍然隨每次訪問而變化,但local保持不變,因此我們可以對其執行智能轉換。
根據您的情況,如果有辦法獲取“當前”或“直接”值,userViewModel.userState.collectAsState()那么您可以在分配給時使用它userState- 那么它應該按您的預期作業。如果沒有這個函式,那我覺得最簡單的就是用另一個變數來存盤本地副本,像這樣:
val _userState by userViewModel.userState.collectAsState() // delegated
val userState = _userState // local copy, immutable
when(userState){
is Response.Error -> userState.error // Smart cast to 'Response.Error' is impossible, because 'userState' is a property that has open or custom getter
Response.Loading -> Unit
is Response.Success -> userState.data // Smart cast to 'Response.Success<User>' is impossible, because 'userState' is a property that has open or custom getter
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/323600.html
下一篇:打字稿-將keyof限制為字串
