【问题标题】:Converted java class file to kotlin makes compilation error将 java 类文件转换为 kotlin 会导致编译错误
【发布时间】:2017-04-05 15:22:04
【问题描述】:

我有一个运行良好的 java 类文件,但如果我将它转换为 Kotlin,就会出现一些问题。这是一个Java版本

 public class CallbackWrapper<T> implements Callback<T> {
   private Wrapper<T> wrapper;

   public CallbackWrapper(Wrapper<T> wrapper) {
      this.wrapper = wrapper;
   }

   public void onFailure(Call<T> call, Throwable t) {
      wrapper.onResult(t, null);
   }

   public void onResponse(Call<T> call, Response<T> response) {
      wrapper.onResult(null, response);
   }

   public interface Wrapper<T> {
      void onResult(@Nullable Throwable t, @Nullable Response<T> response);
   }
}

这就是我毫无问题地使用这个类的方式......

request.enqueue(CallbackWrapper<RegisterResponse> { throwable, response ->
     response?.let { callBack.onResponse(response.body() ?: RegisterResponse()) }
     throwable?.let { callBack.onFailed(throwable.message!!) }
 })

这是转换后的 Kotlin 版本

class CallbackWrapper<T>(private val wrapper: CallbackWrapper.Wrapper<T>) : Callback<T> {

    override fun onFailure(call: Call<T>, t: Throwable) {
        wrapper.onResult(t, null)
    }

    override fun onResponse(call: Call<T>, response: Response<T>) {
        wrapper.onResult(null, response)
    }

    interface Wrapper<T> {
        fun onResult(t: Throwable?, response: Response<T>?)
    }
}

问题是在将其转换为 Kotlin 后,我使用此类的代码块无法正常工作。我不明白它们之间有什么区别。

这里是编译错误日志

Error:(17, 63) Type mismatch: inferred type is (???, ???) -> [ERROR :<ERROR FUNCTION RETURN TYPE>] but CallbackWrapper.Wrapper<RegisterResponse> was expected
Error:(17, 65) Cannot infer a type for this parameter. Please specify it explicitly.
Error:(17, 76) Cannot infer a type for this parameter. Please specify it explicitly.

【问题讨论】:

    标签: java kotlin


    【解决方案1】:

    据我所知,您的代码有两个问题。

    首先,Kotlin 不允许使用 lambda 来实现 Kotlin 函数式接口,因此您的 lambda 无法工作(它确实允许实现 Java 函数式接口,因为 Java 没有正确的函数类型)。所以要调用代码不变,你想改用对象表示法:

    request.enqueue(CallbackWrapper<RegisterResponse>(object : CallbackWrapper.Wrapper<RegisterResponse> {
            override fun onResult(throwable: Throwable?, response: Response<RegisterResponse>?) {
                response?.let { callBack.onResponse(response.body() ?: RegisterResponse()) }
                throwable?.let { callBack.onFailure(throwable.message!!) }
            }
        }))
    

    如果您更喜欢使用 lambda,您可以以不同的方式声明您的 CallbackWrapper 类:

    typealias Wrapper<T> = (t: Throwable?, response: Response<T>?) -> Unit
    class OtherCallbackWrapper<T>(val wrapper: Wrapper<T>) : Callback<T> {
        override fun onFailure(call: Call<T>, t: Throwable) = wrapper.invoke(t, null)
        override fun onResponse(call: Call<T>, response: Response<T>) = wrapper.invoke(null, response)
    }
    

    这就是but CallbackWrapper.Wrapper<RegisterResponse> was expected 部分的处理。

    但这仍然行不通,这让我们想到了错误消息的前半部分是inferred type is (???, ???) -&gt; [ERROR :&lt;ERROR FUNCTION RETURN TYPE&gt;] 的原因。这基本上是类型推断失败。对 callBack 的调用似乎与 CallbackWrapper 隐含的 CallBack 接口不太匹配,我预计这可能与它有关。

    编辑:

    使用更简洁的解决方案添加了对改造问题的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      相关资源
      最近更新 更多