密封类泛型

问题描述 投票:0回答:2

以下代码完美运行。

资源

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

我能做的最好,但给出错误:

如果我投射到......错误消失了

android kotlin kotlin-coroutines kotlin-flow flow
2个回答
1
投票

如果我理解正确,您需要将您的

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)
            }
        }

    }
}

https://pl.kotl.in/Ho_gw0q31


但是如果你想返回

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)
            }
        }

    }
}

1
投票

你的意思是:

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)
            }
        }

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.