【问题标题】:Kotlin: Two Functions Of Same Name With Different Type Function InputsKotlin:具有不同类型函数输入的两个同名函数
【发布时间】:2021-03-29 19:18:43
【问题描述】:

看看下面的代码。

fun stuff(func: () -> Int) {
    println(func().toString())
}

fun stuff(func: () -> String) {
    println(func())
}

fun main() {
    stuff { 1 }
}

这给了我一个奇怪的错误。

Overload resolution ambiguity: public fun stuff(func: () -> Int): Unit defined in root package in file File.kt public fun stuff(func: () -> String): Unit defined in root package in file File.kt
'return' is not allowed here
The integer literal does not conform to the expected type Unit

我不确定为什么并试图解决这个问题。我可以使用 Java 泛型,但我希望在纯 kotlin 中进行这项工作。也可以用参数化类型来做一些事情,比如

fun <T>stuff(func: () -> T)

但是如果调用者不知道它传递了什么,这就不那么优雅了。

我也看到了这个答案:Failsafe withFallback(): why kotlin compiler fails to infer lambda type?

由于以下错误,这不起作用:

Duplicate method name "stuff" with signature "(Lkotlin.jvm.functions.Function0;)V"

因此,基于此错误,我猜想按照自己的意愿执行此操作是不可能的...但我充满希望!

会喜欢这里的一些想法。

【问题讨论】:

  • 我认为它不适用于 java 泛型:Producer 和 Producer 都被编译为 Producer。我认为这也可能是不幸的是它在 kotlin 中不起作用的原因......

标签: kotlin anonymous-function


【解决方案1】:

这是一个奇怪的错误……  当我自己在 IntelliJ 中尝试时,我在两个函数声明中都收到以下错误:

Platform declaration clash: The following declarations have the same JVM signature (stuff(Lkotlin/jvm/functions/Function0;)V)

…后跟两个函数签名。和 then 结束通话:

Overload resolution ambiguity. All these functions match.

…后面还有两个函数签名。

(我根本没有收到您的最后两个错误。  它们可能来自您的代码的不同版本吗?)

第一个告诉你真正的问题是什么:虽然 () -&gt; Int() -&gt; String 在 Kotlin 中是不同的类型,但它们在 Java 字节码中编译成相同的类型。 (原始签名是Lkotlin/jvm/functions/Function0;,它是对kotlin.jvm.functions.Function0 实例的引用,它是Kotlin 运行时用来实现函数引用的接口。  问题在于它是通用的:返回类型由类型参数指示。 )  因此,两个 Kotlin 函数都编译为 相同 函数类型,因此两个版本的 stuff 具有相同的 JVM 签名。这当然是不允许的。

恐怕这也意味着您自己使用泛型来解决它的建议也不会奏效,原因完全相同……

在这种特殊情况下,您可以为Any 参数编写一个方法,因为您可以在任何事情上调用toString()!但当然,这不会更普遍。

(这是 JVM 的普遍烦恼,选择 type erasure 来实现泛型的不幸结果。  你可以在 casesall sorts 中看到它......)

【讨论】:

    【解决方案2】:

    返回类型从不构成方法/函数签名。

    两个方法/函数具有相同的签名,如果它们具有相同的名称和相同的参数,则无论返回类型如何。

    这适用于任何允许重载的语言,否则在 stuff(stuff(...)) 这样的构造中会存在隐含的歧义,无法决定调用哪个外部 stuff()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-29
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多