使用Kotlin改装转换器:类型推断失败

时间:2018-12-13 13:42:16

标签: generics kotlin retrofit

我正在尝试用Kotlin编写一个改装转换器。但是,在尝试返回转换器时,我卡住了:

class JSONRPCConverterFactory private constructor(private val gson : Gson): Converter.Factory() {

    companion object {
        private val MEDIA_TYPE = MediaType.get("application/json")

        fun create(gson: Gson) = JSONRPCConverterFactory(gson)
    }

    inner class JSONRPCRequestBodyConverter<T : JSONRPCRequest<*>>(private val gson: Gson) : Converter<T, RequestBody> {

        override fun convert(value: T): RequestBody? {
            val jsonString = gson.toJson(value, object:TypeToken<T>(){}.type)
            return RequestBody.create(MEDIA_TYPE, jsonString)
        }

    }

    inner class JSONRPCResponseBodyConverter<T>(private val gson: Gson) : Converter<ResponseBody, T> {

        override fun convert(value: ResponseBody): T? {
            return gson.fromJson(value.string(), object:TypeToken<T>(){}.type)
        }

    }

    override fun responseBodyConverter(type: Type, annotations: Array<Annotation>, retrofit: Retrofit): Converter<ResponseBody, *>? {
        if (!hasJSONRPCAnnotation(annotations)) return null

        return JSONRPCResponseBodyConverter(gson)
    }

    override fun requestBodyConverter(type: Type, parameterAnnotations: Array<Annotation>, methodAnnotations: Array<Annotation>, retrofit: Retrofit): Converter<*, RequestBody>? {
        if (!hasJSONRPCAnnotation(methodAnnotations)) return null

        return JSONRPCRequestBodyConverter(gson)
    }

    private fun hasJSONRPCAnnotation(annotations: Array<Annotation>) : Boolean {
        for (annotation in annotations) {
            if (annotation is JSONRPC) return true
        }

        return false
    }
}

错误出现在这两行:

return JSONRPCResponseBodyConverter(gson)

return JSONRPCRequestBodyConverter(gson)
  

类型推断失败:没有足够的信息来推断

中的参数T      

构造函数JSONRPCRequestBodyConverter>(gson:   Gson)

     

请明确指定。

在Java中,可能仅返回new JSONRPCResponseBodyConverter<>(gson)。但是,在kotlin中,该类型是必需的,因此仅添加<>也会失败。

使用Kotlin-lang:Kotlin Serialization Converter查看此转换器,我发现它使用几乎相同的类结构,并且仅返回了一个没有菱形的新转换器,并且可以正常工作。

我想念什么?

1 个答案:

答案 0 :(得分:1)

问题在于JSONRPCResponseBodyConverterJSONRPCRequestBodyConverter都需要一个类型参数T,并且编译器无法在调用站点上推断出这种类型。您看到的示例可能具有某种推断T类型的方式,例如T的参数或它要赋值的类型。

class A<T>(t: T? = null)

val a1 : A<Int> = A() //this will work, it can infer the type from the asigment
val a2 = A(2) //this will work, it can infer the type from the parameter
val a3 = A() //this won't work, the compiler has no way of knowing the type of T