4

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

public class JavaClass {
  public static <E extends CharSequence> E join(E... array) { ... }
  public static <E extends CharSequence> E join(CharSequence separator, E... array) { ... }
}

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

class KtClass {
    fun test(vararg array: String) {
        JavaClass.join(*array)
    }
}

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

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

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

此代码不会编译。编译器无法决定调用哪个方法。错误:

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

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

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



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

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

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

4

3 回答 3

2

我认为这不是 Kotlin 特有的。问题是泛型参数E是类型的CharSequence,因此您的调用变得类似于join("separator", "word1", "word2")确实是模棱两可的,因为第一个参数的E == CharSequence类型与其他参数的类型相同。

于 2017-01-05T19:42:47.767 回答
1

看起来您需要在 Java 中创建一个帮助程序类来解决互操作问题。例如:

public class JavaClassInterop {
    public static <E extends CharSequence> E joinSeparatedBy(CharSequence separator,
                                                             E... array) {
        return JavaClass.join(separator, array);
    }
}

然后你可以同时调用:

import JavaClass.join
import JavaClassInterop.joinSeparatedBy

fun main(args: Array<String>) {
    join(*args)
    joinSeparatedBy("<br>", *args)
}
于 2017-01-05T20:16:38.977 回答
1

tldr

可能您使用可空类型不正确地工作

我为这个错误苦苦挣扎了一段时间,但最终想出了一个解决方案。我一开始有这个

user.items.apply {
        removeAll(otherItems)
        removeAll(otherItems2)
    }

项目集合是一个 MutableSet?所以它可以为空,而 otherItems 集合也可以为空。那么添加之后呢?在应用之前,并将不可为空的集合传递给 removeAll 函数,错误消失了。

user.items?.apply {
        removeAll(otherItems.orEmpty())
        removeAll(otherItems2.orEmpty())
    }
于 2017-11-29T12:25:02.923 回答