Kotlin 错误智能转换为“X”是不可能的,因为“状态”是一个在尝试观察状态时具有开放或自定义 getter 的属性

12 generics kotlin

我尝试观察你所看到的状态,但是当我使用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>()
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)

Jof*_*rey 29

这行:

val userState by userViewModel.userState.collectAsState()
Run Code Online (Sandbox Code Playgroud)

通过委托定义userState,因此编译器无法保证后续读取属性值将给出相同的值。特别是在这里,这意味着从编译器的角度来看,条件中的访问when()和 's 分支中的访问可能不会返回相同的值,因此无法进行智能转换。when

您可以在这里使用中间变量:

val userState by userViewModel.userState.collectAsState()
when(val s = userState){
    is Response.Error   -> s.error
    Response.Loading    -> Unit
    is Response.Success -> s.data
}
Run Code Online (Sandbox Code Playgroud)

现在,由于s是本地变量,val编译器可以保证它在条件和分支中具有相同的值when,并且智能转换可以工作

  • 很好的解决方案!唯一的事情是现在 Android Studio 内置 lint 给出了变量可以内联的提示,没有意识到它会破坏智能转换(( (4认同)