LiveData 不会将类型推断为所需的 return 值
LiveData does not infer the type to desired return value
我已经在我的 viewModel 中调用了 emit()
,但是我不知道为什么我的 LiveDataScope
returns 一个 Resource<Any>
当我定义了 Resource
的类型是 Artist
视图模型
class EventsViewModel(private val useCase: Events):ViewModel() {
val fetchArtistList = liveData(Dispatchers.IO){
try {
val artistList = useCase.getEvents()
emit(artistList)
}catch (e:Exception){
Crashlytics.logException(e.cause)
emit(Resource.error("Error: ",e.message))
}
}
}
用例
class EventsImpl(private val eventsRepo:EventsRepo): Events {
override suspend fun getEvents(): Resource<MutableList<Artist>> = eventsRepo.getEventsDB()
}
回购
class EventsRepoImpl : EventsRepo {
override suspend fun getEventsDB(): Resource<MutableList<Artist>> {
val artistList = mutableListOf<Artist>()
val resultList = FirebaseFirestore.getInstance()
.collection("events")
.get().await()
for (document in resultList) {
val photoUrl = document.getString("photoUrl")
val artistName = document.getString("artistName")
val place = document.getString("place")
val time = document.getString("time")
val day = document.getLong("day")
artistList.add(Artist(photoUrl!!, artistName!!, time!!, place!!, day!!))
}
return Resource.success(artistList)
}
}
但出于某种原因,它没有在我的视图模型中使用 Resource<MutableList<Artist>>
推断类型,而是为 LiveData 提供了 Resource<Any>
:
我在另一个 class 中实现了相同的方法,但 livedata 返回正常,我尝试清除缓存并重新启动,清理并重建但它一直返回相同的结果
为什么不能正确推断类型?
推断正确。您的代码向 Kotlin 建议 LiveData 可以产生两种不同类型的对象。你有这个:
emit(artistList)
还有这个:
emit(Resource.error("Error: ",e.message))
Kotlin 可以从中推断出的最具体的常见类型是 Resource<Any>
,因为它们都是资源对象,但具有不同的泛型类型。
考虑发出一个带有两个子class的密封 class,一个用于数据类型,另一个用于错误类型。
您可以将 Resource
实现更改为此,正如 Doug 所指出的那样
sealed class Resource<out T> {
class Loading<out T> : Resource<T>()
data class Success<out T>(val data: T) : Resource<T>()
data class Failure<out T>(val throwable: Throwable) : Resource<T>()
}
我已经在我的 viewModel 中调用了 emit()
,但是我不知道为什么我的 LiveDataScope
returns 一个 Resource<Any>
当我定义了 Resource
的类型是 Artist
视图模型
class EventsViewModel(private val useCase: Events):ViewModel() {
val fetchArtistList = liveData(Dispatchers.IO){
try {
val artistList = useCase.getEvents()
emit(artistList)
}catch (e:Exception){
Crashlytics.logException(e.cause)
emit(Resource.error("Error: ",e.message))
}
}
}
用例
class EventsImpl(private val eventsRepo:EventsRepo): Events {
override suspend fun getEvents(): Resource<MutableList<Artist>> = eventsRepo.getEventsDB()
}
回购
class EventsRepoImpl : EventsRepo {
override suspend fun getEventsDB(): Resource<MutableList<Artist>> {
val artistList = mutableListOf<Artist>()
val resultList = FirebaseFirestore.getInstance()
.collection("events")
.get().await()
for (document in resultList) {
val photoUrl = document.getString("photoUrl")
val artistName = document.getString("artistName")
val place = document.getString("place")
val time = document.getString("time")
val day = document.getLong("day")
artistList.add(Artist(photoUrl!!, artistName!!, time!!, place!!, day!!))
}
return Resource.success(artistList)
}
}
但出于某种原因,它没有在我的视图模型中使用 Resource<MutableList<Artist>>
推断类型,而是为 LiveData 提供了 Resource<Any>
:
我在另一个 class 中实现了相同的方法,但 livedata 返回正常,我尝试清除缓存并重新启动,清理并重建但它一直返回相同的结果
为什么不能正确推断类型?
推断正确。您的代码向 Kotlin 建议 LiveData 可以产生两种不同类型的对象。你有这个:
emit(artistList)
还有这个:
emit(Resource.error("Error: ",e.message))
Kotlin 可以从中推断出的最具体的常见类型是 Resource<Any>
,因为它们都是资源对象,但具有不同的泛型类型。
考虑发出一个带有两个子class的密封 class,一个用于数据类型,另一个用于错误类型。
您可以将 Resource
实现更改为此,正如 Doug 所指出的那样
sealed class Resource<out T> {
class Loading<out T> : Resource<T>()
data class Success<out T>(val data: T) : Resource<T>()
data class Failure<out T>(val throwable: Throwable) : Resource<T>()
}