Kotlin编译器的类型推断无法选择调用哪个方法(泛型类型的歧义)

Blo*_*ura 5 generics overloading kotlin kotlin-interop

因此,我有一些带有这些签名的 Java 方法(为了简单起见,删除了注释和代码体):

public class JavaClass {
  public static <E extends CharSequence> E join(E... array) { ... }
  public static <E extends CharSequence> E join(CharSequence separator, E... array) { ... }
}
Run Code Online (Sandbox Code Playgroud)

我在 Kotlin 中有一些代码,它调用“join”方法:

class KtClass {
    fun test(vararg array: String) {
        JavaClass.join(*array)
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好; 它将传播可变参数并调用以前的方法签名。好的!

例如,如果我想使用“分隔符”参数调用后一个方法签名,就会出现问题:

class KtClass {
    fun test(vararg array: String) {
        JavaClass.join("<br>", *array)
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码无法编译。编译器无法决定调用哪个方法。错误:

错误:(5, 13) Kotlin:在未完成类型推断的情况下无法在以下候选者中进行选择:public open fun join(vararg array: String!): String!在 JavaClass 中定义 public open fun join(separator: CharSequence!, vararg array: String!): String! 在Java类中定义

我什至无法命名参数,因为 Kotlin 不允许为非 Kotlin 函数命名参数。

编辑:用 Java 方法头中的纯字符串引用替换E泛型类型参数,并且它有效!所以我猜这是类型推断与泛型类型或类似类型的不兼容?



我很确定这必须与扩展运算符(*) 相关。但如果我不使用它,我就无法将 varargs 参数传递array给函数。join

如何在不接触 Java 代码的情况下解决这个问题?

是的,我知道有 Array.joinToString 扩展函数,但这只能解决这种特殊情况。我需要知道一个通​​用的解决方案。

Oli*_*ain 2

我不认为这是 Kotlin 特有的。问题在于,泛型参数的类型E是这样的,CharSequence因此您的调用join("separator", "word1", "word2")实际上是不明确的,因为第一个参数的类型E == CharSequence与其他参数的类型相同。