【问题标题】:Why can't Kotlin super type parameters be inferred from constructor?为什么不能从构造函数中推断出 Kotlin 超类型参数?
【发布时间】:2025-12-12 02:20:03
【问题描述】:

在 Kotlin 中,如果我们有一个带构造函数的类:

open class Wrapper<T>(val value: T)

我们可以在不指定类型参数的情况下调用构造函数:

val wrapped = Wrapper("value")

指定类型参数(例如Wrapper&lt;String&gt;("value"))是多余的,IntelliJ 会告诉你。

但是,如果构造函数调用是extends 子句,则类型参数是必需的。例如

class StringWrapper : Wrapper<String>("value") // compiles
class StringWrapper : Wrapper("value") // does not compile

在这个看似非常相似的情况下,为什么不能推断出类型参数?

【问题讨论】:

标签: generics kotlin type-inference


【解决方案1】:

类型参数当然可以在这种情况下被推断出来,但是编译器中还没有代码可以做到这一点。 JetBrains 团队成员 Stanislav Erokhin 在 2017 年对此 here 发表了评论。

[...] 现在编译器强制用户为父级声明类型参数 明确分类。

让我们尝试一下。编译器源代码中有问题的检查是here

if (currentArguments.size != currentParameters.size) {
    c.trace.report(
        WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(
            qualifierPart.typeArguments ?: qualifierPart.expression,
            currentParameters.size, classifierDescriptorChain[index]
        )
    )
    return null
}

如果我们删除该检查会怎样?原来我们摆脱了

error: one type argument expected for class Wrapper<T>

但我们并没有走得更远;相反,我们得到

error: type arguments should be specified for an outer class 'Wrapper'. Use full class name to specify them

让它发挥作用需要更大的改变......

所以,简而言之,理论上是可行的,但还没有实现。

【讨论】: