【问题标题】:Reason why type inference failed in KotlinKotlin 类型推断失败的原因
【发布时间】:2019-07-26 06:48:50
【问题描述】:


有人可以帮我了解一下 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 的情况下解决问题? 提前谢谢!

P.S. kotlin 版本 = '1.3.21'

【问题讨论】:

    标签: oop generics kotlin type-inference


    【解决方案1】:

    通过在您的方法(toPayloadObjectconvertToSpecificMessageType)前面声明 &lt;reified T : Any&gt;,您将为您的方法引入一个新类型参数 T,它与 classA 的类型参数无关同名T

    T 的方法局部声明 阴影 TclassA 上。

    因此,当您执行 val result = convertToSpecificMessageType(body) 时,Kotlin 根本没有上下文可以用来推断类型。虽然您在 classA 中的一个方法中,但 classA 中的 T 未被方法 convertToSpecificMessageType 使用。

    解决方案?

    您不能在类上使用具体类型,因此:

    • 您可以删除 &lt;reified T : Any&gt; 部分并将类对象传递给方法
    • 或者你保留它,但是你在调用val result = convertToSpecificMessageType&lt;MyType&gt;(body)val result : MyType = convertToSpecificMessageType(body)中的方法时提供上下文

    【讨论】:

      猜你喜欢
      • 2018-08-21
      • 2020-12-30
      • 2018-05-15
      • 2018-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多