Ковариантный параметр типа в Scala должен быть инвариантным в интерфейсе Java - PullRequest
12 голосов
/ 15 сентября 2010

У меня есть черта, которая выглядит следующим образом (некоторая дополнительная информация может быть найдена на этом связанном мной вопросе , хотя я не думаю, что он нужен для этого вопроса)

trait Extractor[-A,+B] {
  def extract(d:A):B
  //lots of other things
}

Чтобы использовать это в существующей среде Java, я бы хотел, чтобы в Extractor была либо функция, которая возвращает Comparator[B] (будучи java.util.Comparator ), либо, что еще лучше, расширение Comparator[A].Это создает проблему, поскольку параметр типа Comparator должен быть инвариантным, а A - контравариантным, а B - ковариантным.

Так что я получаю следующие ошибки:

scala> import java.util.Comparator
import java.util.Comparator

scala> trait Extractor[-A,+B] extends Comparator[A]
<console>:6: error: contravariant type A occurs in invariant position in type [-A,+B]java.lang.Object with java.util.Comparator[A] of trait Extractor
       trait Extractor[-A,+B] extends Comparator[A]
             ^


scala> trait Extractor[-A, +B] {                 
     |   def comp:Comparator[B]
     | }
<console>:7: error: covariant type B occurs in invariant position in type => java.util.Comparator[B] of method comp
         def comp:Comparator[B]
             ^

Видите ли вы какой-либо выход из этого или это только один из тех случаев, когда "использование java-обобщений в scala вредит"?

Ответы [ 2 ]

12 голосов
/ 15 сентября 2010

С помощью границ типов можно сделать следующее:

scala> trait Extractor[-A, +B] {
     | def comp:Comparator[_ <: B]
     | }
defined trait Extractor
7 голосов
/ 15 сентября 2010

Вы можете сделать Extractor[A,B] продление Comparator[A], используя аннотацию @uncheckedVariance.

scala> import scala.annotation.unchecked.uncheckedVariance
import scala.annotation.unchecked.uncheckedVariance

scala> trait Extractor[-A,+B] extends java.util.Comparator[A @uncheckedVariance]
defined trait Extractor

@uncheckedVariance здесь безопасно, поскольку Comparator можно было бы определить как Comparator[-T].Было обсуждение вокруг создания Ordering коварианта для Scala 2.8 с использованием этой аннотации.

Редактирование См. этот вопрос для получения дополнительной информации о @uncheckedVariance.

...