Kotlin编译器的types推断不能选择调用哪个方法(与genericstypes不一致)
所以,我有一些这些签名的Java方法(为简单起见,删除了注释和代码体):
public class JavaClass { public static E join(E... array) { ... } public static E join(CharSequence separator, E... array) { ... } }
我在Kotlin中有一些代码,它调用了’join’方法:
class KtClass { fun test(vararg array: String) { JavaClass.join(*array) } }
到现在为止还挺好; 它会传播可变参数并称之为方法签名。 好的!
例如,如果我想用“分隔符”参数来调用后一个方法签名,就会出现问题:
class KtClass { fun test(vararg array: String) { JavaClass.join("
", *array) } }
这段代码不会编译。 编译器无法决定调用哪个方法。 错误:
错误:(5,13)Kotlin:不能完成types推断之间的以下候选人之间:public open fun join(vararg array:String!):String! 在JavaClass public open fun join中定义(分隔符:CharSequence!,可变长度数组:String!):String! 在JavaClass中定义
我甚至不能说出这些论点,因为Kotlin没有让参数命名为非Kotlin函数。
编辑:用Java方法头中的普通字符串引用替换Egenericstypes参数,它的工作! 所以我想这是与genericstypes或类似的types推断不兼容?
我非常肯定这是一个与传播运算符 (*)的东西。 但是,如果我不使用它,我不能将varargs参数array
传递给join
函数。
我怎样才能解决这个问题,而不必触摸Java代码?
是的,我知道有Array.joinToString扩展函数,但是这只会解决这个特殊情况。 我需要知道一个通用的解决方案。
我不认为这是Kotlin特定的。 问题是generics参数E
是CharSequence
types的,所以你的调用变成类似于E == CharSequence
join("separator", "word1", "word2")
,这实际上是自第一个参数以来不明确的。与其他参数的types相同。
看起来你需要在Java中创建一个辅助类来弥补互操作问题。 例如:
public class JavaClassInterop { public static E joinSeparatedBy(CharSequence separator, E... array) { return JavaClass.join(separator, array); } }
那么你可以调用两个:
import JavaClass.join import JavaClassInterop.joinSeparatedBy fun main(args: Array) { join(*args) joinSeparatedBy("
", *args) }
tldr
可能你工作不正确的可空types
我一直在努力处理这个错误,但终于find了一个解决方案。 起初我有这个
user.items.apply { removeAll(otherItems) removeAll(otherItems2) }
items集合是一个MutableSet? 所以它是可以空的,其他的Item集合也可以是空的。 所以添加后? 在应用之前,并将不可空的集合传递给removeAll函数,错误消失。
user.items?.apply { removeAll(otherItems.orEmpty()) removeAll(otherItems2.orEmpty()) }