[英]Kotlin compiler's type inference can't choose which method to call (ambiguity with generic types)
所以,我有一些带有这些签名的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中有一些代码,它们调用'join'方法:
class KtClass {
fun test(vararg array: String) {
JavaClass.join(*array)
}
}
到现在为止还挺好; 它将传播varargs并调用前方法签名。 好的!
例如,如果我想使用'separator'参数调用后一种方法签名,则会出现问题:
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扩展函数,但这只能解决这个特殊情况。 我需要知道一个通用的解决方案。
我不认为这是特定的Kotlin。 问题是泛型参数E
的类型是CharSequence
所以你的调用变成了join("separator", "word1", "word2")
,它实际上是第一个参数的模糊,类型为E == CharSequence
与其他args的类型相同。
看起来您需要在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)
}
tldr
可能你错误地使用可空类型
我在这个错误中挣扎了一段时间,但终于想出了一个解决方案。 我起初有这个
user.items.apply {
removeAll(otherItems)
removeAll(otherItems2)
}
物品集合是一个MutableSet? 所以它可以为空,而其他Items集合也可以为空。 添加后呢? 在apply之前,将非可空集合传递给removeAll函数,错误消失了。
user.items?.apply {
removeAll(otherItems.orEmpty())
removeAll(otherItems2.orEmpty())
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.