Scala разрешает неправильное переопределение в Comparator.thenComparing - PullRequest
0 голосов
/ 09 февраля 2019

Я пытаюсь перевести следующий код 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, но мне интересно понять, почему это не получается.)

1 Ответ

0 голосов
/ 09 февраля 2019

С учетом определений

val comparator: Comparator[String] = (t1, t2) => 0
val f: function.Function[String, String] = s => s

следующее не с той же ошибкой, что и в вашем вопросе:

comparator.thenComparing(f)

, но успешно компилируется:

comparator.thenComparing[String](f)

Это очень распространенный тип ошибок, которые возникают регулярно, когда кто-то пытается использовать универсальные интерфейсы Java из Scala.Причина заключается в том, что Java-вариация использования сайта не очень хорошо сочетается с Scala-декларацией сайта-вариации, поэтому Java Comparator<? super T> преобразуется в подстановочный тип Comparator[_ >: T], и это каким-то образом путает алгоритм вывода типа (особенно если вы комбинируете его сперегружены методы и SAM).Однако, как только эта проблема распознается, ее очень легко решить путем явного указания параметров типа, в этом случае достаточно добавить явный [String].

...