kotlin - Kotlin 类型擦除 - 为什么仅在泛型类型上不同的函数可编译,而仅在返回类型上不同的函数不是?
问题描述
在研究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
,而且我们知道,泛型在运行时被删除,为什么这个工作,而没有泛型类型的变体没有?
在字节码中,只允许返回类型不同的方法(已经在上面链接的答案中描述)。
欢迎任何提示、来源和/或参考。
现在也在讨论.kotlinlang.org添加了这个问题。
解决方案
这些函数编译或不编译的原因与 Kotlin 的重载解析规则有关。Kotlin 不使用预期的类型来解决重载,所以当你调用这个函数时:
val x = bar(listOf(""))
... Kotlin 编译器无法确定类型,并且不允许您通过x
显式指定类型来消除调用歧义。
在第二种情况下,不存在重载解决问题,因为函数具有不同的参数类型,并且不存在 JVM 名称冲突问题,因为函数具有不同的返回类型(因此不同的擦除签名)。因此,代码编译。
推荐阅读
- c++ - 嵌套if else语句c ++
- matlab - 如何在不获取单个元素的情况下将数组按元素分配给数组?
- linux - 用于匹配列并将新列从文件添加到表中的 shell 脚本
- hibernate - hbernate org.hibernate.PersistentObjectException:未初始化的代理传递给 org.hibernate.event.internal.DefaultSave 的 save()
- vba - 试图从工作表子调用模块子:'运行时错误:1004'
- spotipy - 无效的 spotipy 重定向 URL
- android - Xamarin Android 项目中不存在类型或命名空间名称“支持”
- delphi - Firedac 更改警报器
- elasticsearch - 使用 wagtail 弹性搜索功能进行无休止的滚动
- google-apps-script - Google 数据工作室连接器:“抱歉,我们遇到错误,无法完成您的请求。”