在Kotlin中,如果我们有一个带有构造函数的类:
open class Wrapper<T>(val value: T)
我们可以在不指定type参数的情况下调用构造函数:
val wrapped = Wrapper("value")
指定类型参数(例如Wrapper<String>("value")
)是多余的,IntelliJ会告诉您。
但是,如果构造函数调用是extends子句,则类型参数是必需的。例如
class StringWrapper : Wrapper<String>("value") // compiles
class StringWrapper : Wrapper("value") // does not compile
为什么在这种看似非常相似的情况下无法推断出类型参数?
答案 0 :(得分: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
要使其正常工作,将需要进行更大的更改...
因此,简而言之,从理论上讲这是可能的,但尚未实现。
答案 1 :(得分:0)
Kotlin中的类型推断仅限于变量和函数,并且仅在某些情况下可用。例如:
val s = "42"
s将具有String类型,在这种情况下:
fun f() = { "42" }
类型为f() : String
但是kotlin不能推断Type变量的类型,除非您告诉它。