Kotlin类型擦除-为什么只编译通用类型不同的函数却不能编译仅返回类型不同的函数?

时间:2018-08-30 08:14:51

标签: kotlin type-erasure

在研究answerHow 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中进行了描述)。

欢迎任何提示,来源和/或参考。

添加了this question now also at discuss.kotlinlang.org

1 个答案:

答案 0 :(得分:3)

这些函数编译或不编译的原因与Kotlin的重载解决规则有关。 Kotlin不使用预期的类型来解决重载,因此,当您调用此函数时:

 val x = bar(listOf(""))

... Kotlin编译器无法确定类型,并且不允许您通过明确指定x的类型来消除调用的歧义。

在第二种情况下,由于函数具有不同的参数类型,因此不存在重载解析问题,并且由于函数具有不同的返回类型(因此具有不同的擦除签名),因此也没有JVM名称冲突问题。因此,代码会编译。