Scala 解析为 Comparator.thenComparing 中的错误覆盖
Scala resolving to wrong override in Comparator.thenComparing
我正在尝试翻译以下 Java 代码:
import java.util.Comparator;
public class ComparatorTestJava {
public static void test() {
Comparator<String> cmp = (s1, s2) -> 0;
cmp = cmp.thenComparing(s -> s);
}
}
进入 Scala。我认为这应该有效:
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
})
}
但失败并出现以下错误:
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] {
看起来 Scala 编译器确信我正在尝试使用 thenComparing(Comparator)
而不是 thenComparing(Function)
。有什么办法可以告诉我它是哪个吗?或者这实际上不是问题所在?
(我意识到在 Scala 中还有其他可能更惯用的方法来构建比较器,但我有兴趣了解为什么会失败。)
根据定义
val comparator: Comparator[String] = (t1, t2) => 0
val f: function.Function[String, String] = s => s
以下失败并出现与您问题中相同的错误:
comparator.thenComparing(f)
但是编译成功:
comparator.thenComparing[String](f)
这是一种非常常见的错误类型,每当有人尝试使用 Scala 中的通用 Java 接口时,它就会定期发生。原因是Java的use-site variance和Scala的declaration-site variance配合不好,所以Java的Comparator<? super T>
翻译成了通配符类型Comparator[_ >: T]
,并且它以某种方式混淆了类型推断算法(特别是如果您将它与重载方法和 SAM 结合使用)。但是,一旦识别出来,通过显式指定类型参数就很容易解决问题,在这种情况下,显式添加一个 [String]
就足够了。
我正在尝试翻译以下 Java 代码:
import java.util.Comparator;
public class ComparatorTestJava {
public static void test() {
Comparator<String> cmp = (s1, s2) -> 0;
cmp = cmp.thenComparing(s -> s);
}
}
进入 Scala。我认为这应该有效:
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
})
}
但失败并出现以下错误:
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] {
看起来 Scala 编译器确信我正在尝试使用 thenComparing(Comparator)
而不是 thenComparing(Function)
。有什么办法可以告诉我它是哪个吗?或者这实际上不是问题所在?
(我意识到在 Scala 中还有其他可能更惯用的方法来构建比较器,但我有兴趣了解为什么会失败。)
根据定义
val comparator: Comparator[String] = (t1, t2) => 0
val f: function.Function[String, String] = s => s
以下失败并出现与您问题中相同的错误:
comparator.thenComparing(f)
但是编译成功:
comparator.thenComparing[String](f)
这是一种非常常见的错误类型,每当有人尝试使用 Scala 中的通用 Java 接口时,它就会定期发生。原因是Java的use-site variance和Scala的declaration-site variance配合不好,所以Java的Comparator<? super T>
翻译成了通配符类型Comparator[_ >: T]
,并且它以某种方式混淆了类型推断算法(特别是如果您将它与重载方法和 SAM 结合使用)。但是,一旦识别出来,通过显式指定类型参数就很容易解决问题,在这种情况下,显式添加一个 [String]
就足够了。