在研究answer的How does erasure work in Kotlin?时,我发现了一些我还不了解的东西,也没有找到任何资料来说明为什么。
为什么以下内容无法编译?
fun bar(foo: List<*>) = ""
fun bar(foo: List<*>) = 2
以下是什么?
fun bar(foo: List<String>) = ""
fun bar(foo: List<Int>) = 2
对我来说,当添加甚至不使用的泛型类型时,它甚至变得更加好奇,即以下代码也可以编译:
fun bar(foo: List<*>) = ""
fun <T> bar(foo: List<*>) = 2 // T isn't even used
由于最后一个甚至不使用T
,并且众所周知,泛型在运行时被删除,为什么这样做有效,而没有泛型类型的变体却不起作用?
在字节码方法内,仅允许返回类型不同的字节方法(已在above linked answer中进行了描述)。
欢迎任何提示,来源和/或参考。
答案 0 :(得分:3)
这些函数编译或不编译的原因与Kotlin的重载解决规则有关。 Kotlin不使用预期的类型来解决重载,因此,当您调用此函数时:
val x = bar(listOf(""))
... Kotlin编译器无法确定类型,并且不允许您通过明确指定x
的类型来消除调用的歧义。
在第二种情况下,由于函数具有不同的参数类型,因此不存在重载解析问题,并且由于函数具有不同的返回类型(因此具有不同的擦除签名),因此也没有JVM名称冲突问题。因此,代码会编译。