【问题标题】:Can not use inline function of retrofit不能使用改造的内联功能
【发布时间】:2020-08-09 21:36:34
【问题描述】:

我正在尝试使用 Retrofit 的响应创建一个内联函数,但是当我按下 . 并尝试调用该函数不可见时,我尝试不调用它并且它是可见的。

我有这个

@GET("url")
suspend fun getModel(): Response<ModelEntity>

我的内联函数是

inline fun <T, R> safeCall(
    block: () -> Response<T>,
    transform: (T) -> R,
    errorFactory: FailureFactory = FailureFactory()
): Either<ErrorEntity, R> =
    try {
        val result = block()
        when (result.isSuccessful) {
            true -> Either.Right(transform(result.body()!!))
            false -> Either.Left(errorFactory.handleCode(result.code()))
        }
    } catch (exception: IOException) {
        Either.Left(errorFactory.handleException(exception))
    }

但我不能调用类似的东西

service.myList().safeCall(...)

即使它返回 Response&lt;T&gt;

我的想法是这样称呼它

override fun getMessages() =
   service.getMessages()
         .safeCall(transform = { it.map { msgs-> msgs.toDomain() }})
}

【问题讨论】:

    标签: android generics kotlin retrofit


    【解决方案1】:

    你需要做你的功能:

    1. 您希望调用它的类型的扩展。
    2. 使 transform 最后一个参数在大括号外使用(推荐在干净的架构中,不是必需的)。

    你可以这样实现你的功能:

    inline fun <T, R> Response<T>.safeCall(
        errorFactory: FailureFactory = FailureFactory(),
        transform: (T) -> R
    ): Either<ErrorEntity, R> =
        when (this.isSuccessful) {
            true -> Either.Right(transform(body()!!))
            false -> Either.Left(errorFactory.handleCode(code()))
        }
    

    现在,由于您的 safeCall 是 Response 的扩展,现在您可以在这样的响应中调用它:

    // response is of type Response<T> where T is Any?
    response.safeCall(myErrorFactory) { it.map { msgs-> msgs.toDomain() } }
    

    编辑:

    如果你想捕获异常,在进行调用时,你可以使用这种方法:

    inline fun <T, R> safeCall(
        block: () -> Response<T>,
        errorFactory: FailureFactory = FailureFactory(),
        transform: (T) -> R
    ): Either<ErrorEntity, R> = ... // your original function body
    

    调用这个函数:

    // myErrorFactory optional
    safeCall(service::mylist, myErrorFactory) { it.map { msgs-> msgs.toDomain() } }
    safeCall(service::getMessages, myErrorFactory) { it.map { msgs-> msgs.toDomain() } }
    

    【讨论】:

    • 有什么办法可以避免双重爆炸!!在身体上?
    • 有什么区别?又怎么能避免!!在 body()??
    • @StuartDTO,区别在于将函数作为参考传递,或者你如何调用函数。而且你不能删除!因为它可以返回null。在 http 中可以有一个只有空正文的标头请求。
    • @StuartDTO 您可以通过指定一个默认值(如空字符串)来避免它。 result.body() ?: "",如果返回结果为 null 则将替换为空字符串,而不是抛出错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 2020-08-24
    • 1970-01-01
    • 2021-05-08
    相关资源
    最近更新 更多