为什么不能从构造函数中推断出 Kotlin 超类型参数?

Why can't Kotlin super type parameters be inferred from constructor?

在 Kotlin 中,如果我们有一个 class w/constructor:

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

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

val wrapped = Wrapper("value")

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

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

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

为什么在这种看似非常相似的情况下无法推断出类型参数?

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

[...] for now compiler force users declare type arguments for parent class explicitly.

让我们来试验一下。编译器源代码中有问题的检查是 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

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

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