2010-09-15 3 views
12

У меня есть черта, которая выглядит следующим образом (некоторые дополнительную информацию можно найти на сайте this related question by myself, хотя я не думаю, что это необходимо для этого вопроса)Ковариантное Typeparameter в Скале должен быть инвариантным в Java интерфейс

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

для использования в существующих рамках Java я хотел бы эту Extractor либо иметь функцию, которая возвращает Comparator[B] (будучи java.util.Comparator) или даже лучше продлить Comparator[A]. Теперь возникает проблема, потому что параметр типа Comparator s должен быть инвариантным, а 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 дженериков в Ла Скала болит»?

ответ

12

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

scala> trait Extractor[-A, +B] { 
    | def comp:Comparator[_ <: B] 
    | } 
defined trait Extractor 
+0

спасибо. Это работает. Код еще не запущен, но ваш код и эффективное объявление компилятора скомпилируют сохранение и звук. Огромное спасибо. – Agl

+0

Я знаю, что это совсем другой вопрос, но есть ли хорошая бумага/учебник/блог, охватывающий типы и варианты? Я уже читал об этом, но можно было утверждать, что я не слишком многому научился от них;) (с другой стороны, может быть, это только я. Так что все они все читают снова) – Agl

+2

Это очень хорошо (хотя это не вверх -to-date - не имеет информации о некоторых характеристиках 2.8): http://programming-scala.labs.oreilly.com/ch12.html –

7

Вы можете сделать 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]. Был discussion вокруг создания Ordering ковариант для Scala 2.8, используя эту аннотацию.

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

+0

Ух, это тоже хорошо. На самом деле это может быть версия, которая заканчивается в моем коде. , , как только я найду время, чтобы прочитать этот поток, который вы опубликовали. Большое спасибо! – Agl