Kotlin编译器的类型推断不能选择调用哪个方法(带有泛型类型的歧义)
所以,我有一些这些签名的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) } }
到现在为止还挺好; 它会传播可变参数并称之为方法签名。 好的!
例如,如果我想用“分隔符”参数来调用后一个方法签名,就会出现问题:
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中定义(分隔符:CharSequence!,可变长度数组:String!):String! 在JavaClass中定义
我甚至不能说出这些论点,因为Kotlin没有让参数命名为非Kotlin函数。
编辑:用Java方法头中的普通字符串引用替换E泛型类型参数,它的工作! 所以我想这是与泛型类型或类似的类型推断不兼容?
我非常确定这是一个扩散运算符 (*)。 但是,如果我不使用它,我不能将varargs参数array
传递给join
函数。
我怎样才能解决这个问题,而不必触摸Java代码?
是的,我知道有Array.joinToString扩展函数,但是这只会解决这个特殊情况。 我需要知道一个通用的解决方案。
我不认为这是Kotlin特定的。 问题是泛型参数E
是CharSequence
类型的,所以你的调用变成类似于E == CharSequence
join("separator", "word1", "word2")
,这实际上是自第一个参数以来不明确的。与其他参数的类型相同。
看起来你需要在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) }