zal*_*ale 6 generics scala scala-java-interop
我正在尝试翻译以下Java代码:
import java.util.Comparator;
public class ComparatorTestJava {
public static void test() {
Comparator<String> cmp = (s1, s2) -> 0;
cmp = cmp.thenComparing(s -> s);
}
}
Run Code Online (Sandbox Code Playgroud)
进入斯卡拉.我认为这应该有效:
import java.util.{Comparator, function}
object ComparatorTest {
var comparator: Comparator[String] = (t1, t2) ? 0
comparator = comparator.thenComparing(new function.Function[String, String] {
override def apply(t: String): String = t
})
}
Run Code Online (Sandbox Code Playgroud)
但它失败并出现以下错误:
Error:(7, 41) type mismatch;
found : java.util.function.Function[String,String]
required: java.util.Comparator[? >: String]
comparator = comparator.thenComparing(new function.Function[String, String] {
Run Code Online (Sandbox Code Playgroud)
看起来Scala编译器确信我正在尝试使用thenComparing(Comparator)
而不是thenComparing(Function)
.有什么方法可以告诉它它是什么?或者这实际上不是问题?
(我意识到还有其他的,也许更惯用的方法在Scala中构建比较器,但我很想知道为什么会失败.)
鉴于定义
val comparator: Comparator[String] = (t1, t2) => 0
val f: function.Function[String, String] = s => s
Run Code Online (Sandbox Code Playgroud)
以下错误与您的问题中的错误相同:
comparator.thenComparing(f)
Run Code Online (Sandbox Code Playgroud)
但这成功编译:
comparator.thenComparing[String](f)
Run Code Online (Sandbox Code Playgroud)
每当尝试使用Scala的通用Java接口时,这是一种非常常见的错误类型.原因是Java的使用站点差异与Scala的声明站点方差不相符,因此Java会Comparator<? super T>
转换为通配符类型Comparator[_ >: T]
,并且它会以某种方式混淆类型推断算法(特别是如果将它与重载方法和SAM结合使用).但是,一旦识别出来,通过明确指定类型参数就可以很容易地解决问题,在这种情况下,添加显式[String]
就足够了.