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

8
在 Kotlin 中,如果我们有一个带构造函数的类:
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

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

1
我已经在 https://youtrack.jetbrains.com/issue/KT-43594 上报告了这个问题。 - mhsmith
1个回答

3
在这种情况下,类型参数可能会被推断出来,但目前编译器中没有相应的代码。JetBrains团队成员Stanislav Erokhin在2017年的这里发表了评论。

[...] 目前编译器强制要求用户显式声明父类的类型参数。

让我们进行一些实验。编译器源代码中涉及到的检查在这里
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

要实现它需要进行更大的改变......

简而言之,理论上是可能的,但目前尚未实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接