Kotlin 类型擦除 - 为什么仅在泛型类型上不同的函数可编译,而仅在 return 类型上不同的函数不可编译?
Kotlin type erasure - why are functions differing only in generic type compilable while those only differing in return type are not?
在 of 上工作时,我发现了一些我还不理解的东西,也没有找到任何原因。
为什么以下无法编译?
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
并且正如我们所知,泛型在运行时被删除,为什么这个可以工作,而没有泛型类型的变体却不能?
在字节码中,只允许 return 类型不同的方法(已在 中描述)。
欢迎任何提示、来源 and/or 参考。
这些函数编译或不编译的原因与Kotlin的重载决议规则有关。 Kotlin 不使用预期的类型来解析重载,所以当你调用这个函数时:
val x = bar(listOf(""))
...Kotlin 编译器无法确定类型,并且不允许您通过显式指定 x
的类型来消除调用歧义。
在第二种情况下,不存在重载解析问题,因为函数具有不同的参数类型,并且不存在 JVM 名称冲突问题,因为函数具有不同的 return 类型(因此具有不同的擦除签名) .因此,代码编译。
在
为什么以下无法编译?
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
并且正如我们所知,泛型在运行时被删除,为什么这个可以工作,而没有泛型类型的变体却不能?
在字节码中,只允许 return 类型不同的方法(已在
欢迎任何提示、来源 and/or 参考。
这些函数编译或不编译的原因与Kotlin的重载决议规则有关。 Kotlin 不使用预期的类型来解析重载,所以当你调用这个函数时:
val x = bar(listOf(""))
...Kotlin 编译器无法确定类型,并且不允许您通过显式指定 x
的类型来消除调用歧义。
在第二种情况下,不存在重载解析问题,因为函数具有不同的参数类型,并且不存在 JVM 名称冲突问题,因为函数具有不同的 return 类型(因此具有不同的擦除签名) .因此,代码编译。