以下代码完美运行。
sealed class Resource<out T:Any>{
data class Success<out T:Any> (val data:T):Resource<T>()
data class Error(val exception: Exception):Resource<Nothing>()
data class Loading(val message:String):Resource<Nothing>()
}
fun simple(): Flow<Resource<String>> = flow {
delay(100)
emit(Resource.Loading("Loading message..."))
delay(100)
emit(Resource.Error(Exception("Error Message")))
delay(100)
emit(Resource.Success("Value=X"))
}
suspend fun <T> Flow<T>.process(
onLoading: ((T)->Unit),
onError: ((T)->Unit),
onSuccess: ((T)->Unit)) {
collect { value ->
when ( value ) {
is Resource.Error -> {
onError(value)
}
is Resource.Loading -> {
onLoading(value)
}
is Resource.Success<*> -> {
onSuccess(value)
}
}
}
}
fun job1() {
viewModelScope.launch {
simple().process({
}, {
}, {
})
}
}
从图中可以看出,所有回调都返回
Resource<String>
类型。是否可以为Resource.Loading
回调返回onLoading
,为Resource.Error
回调返回onError
并为Resource.Success<String>
回调返回onSuccess
?
我想要实现的是:
fun job1() {
viewModelScope.launch {
simple().process({Resource.Loading
}, {Resource.Error
}, {Resource.Success<String>
})
}
}
另一个问题是编译器强迫我写
Resource.Success<*>
。否则报错:
这样写有什么坏处吗?
编辑_1:
suspend fun <T: Resource<Any>> Flow<T>.process(
onLoading: ((Resource.Loading)->Unit),
onError: ((Resource.Error)->Unit),
onSuccess: ((T)->Unit)) {
collect { value ->
when ( value ) {
is Resource.Error -> {
onError(value)
}
is Resource.Loading -> {
onLoading(value)
}
is Resource.Success<*> -> {
onSuccess(value)
}
}
}
}
Edit_2
我能做的最好,但给出错误:
如果我投射到......错误消失了
如果我理解正确,您需要将您的
process
方法更改为那个
suspend fun <T : Any> Flow<Resource<T>>.process(
onLoading: ((Resource.Loading) -> Unit),
onError: ((Resource.Error) -> Unit),
onSuccess: ((T) -> Unit)
) {
collect { value ->
when (value) {
is Resource.Error -> {
onError(value)
}
is Resource.Loading -> {
onLoading(value)
}
is Resource.Success<*> -> {
onSuccess(value.data as T)
}
}
}
}
但是如果你想返回
onSuccess
整个Resource.Success
你可以那样做
suspend fun <T : Any> Flow<Resource<T>>.process(
onLoading: ((Resource.Loading) -> Unit),
onError: ((Resource.Error) -> Unit),
onSuccess: ((Resource.Success<T>) -> Unit)
) {
collect { value ->
when (value) {
is Resource.Error -> {
onError(value)
}
is Resource.Loading -> {
onLoading(value)
}
is Resource.Success<T> -> {
onSuccess(value)
}
}
}
}
你的意思是:
suspend fun Flow<Resource<*>> .process(
onLoading: ((Resource.Loading)->Unit),
onError: ((Resource.Error)->Unit),
onSuccess: ((Resource.Success<*>)->Unit)) {
collect { value ->
when ( value ) {
is Resource.Error -> {
onError(value)
}
is Resource.Loading -> {
onLoading(value)
}
is Resource.Success -> {
onSuccess(value)
}
}
}
}