Kotlin中类型推断失败的原因

时间:2019-03-04 21:45:41

标签: oop generics kotlin type-inference


有人可以帮我绕过Kotlin编译器行为吗?
该程序的目的是将输入字符串转换为相应的类型(BMsgCMsg) 并在控制台中打印结果。
但是,我从编译器收到以下消息:

  

“类型推断失败。没有足够的信息来推断参数T   ...”

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper

abstract class classA<T> {
    fun handle(body: String) {
        val result = convertToSpecificMessageType(body) // This line fails
        printResult(result)
        otherImportantStuff()
    }

    abstract fun otherImportantStuff()

    private inline fun <reified T : Any> String.toPayloadObject(): T =
            jacksonObjectMapper().readValue(this, T::class.java)

    private inline fun  <reified T : Any> convertToSpecificMessageType(body: String): T = body.toPayloadObject()
    private fun printResult(result: T) = println("result = $result")
}

class classB : classA<BMsg>() {
    override fun otherImportantStuff() = print("important stuff of class B")
}

class classC : classA<CMsg>() {
    override fun otherImportantStuff() = print("important stuff of class C")
}

sealed class Msg
data class BMsg(val x: String) : Msg()
data class CMsg(val y: Int) : Msg()

fun main() {
    classB().handle("{\"x\" : \"aaa\"}")
    classC().handle("{\"y\" : 5}")
}    

尽管我找到了一种解决方法-将convertToSpecificMessageType方法声明为abstract 并在classB / classC中覆盖,我想知道(1)是什么原因使编译器抱怨 (2)是否有一种方法可以解决该问题而不覆盖convertToSpecificMessageType? 预先谢谢你!

PS kotlin版本='1.3.21'

1 个答案:

答案 0 :(得分:1)

通过在方法(<reified T : Any>toPayloadObject)前面声明convertToSpecificMessageType,您将为您的方法引入一个新的类型参数T,该参数与类型为classA的{​​{1}}类型参数。

T的方法本地声明阴影 T上的T

因此,当您执行classA时-Kotlin根本没有可用于推断其类型的上下文。尽管您使用的是val result = convertToSpecificMessageType(body)中的方法,但是方法classA并未使用classA的T

解决方案?

您不能在类上使用归一化类型,因此:

  • 您可以删除convertToSpecificMessageType部分并将类对象传递给方法
  • 或将其保留在此处,但是在调用<reified T : Any>val result = convertToSpecificMessageType<MyType>(body)中的方法时会提供上下文