2010-09-15 10 views
12

ho una caratteristica che assomiglia a questo (alcune ulteriori informazioni sono disponibili all'indirizzo this related question by myself anche se non credo, ce n'è bisogno per questa domanda)covariante Typeparameter a Scala ha bisogno di essere invarianti in interfaccia java

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

per utilizzare questo in un quadro Java esistente Vorrei che questo Extractor di avere sia una funzione che restituisce un Comparator[B] (essendo java.util.Comparator) o, meglio ancora estendere Comparator[A]. Ora ciò pone un problema perché il parametro di tipo Comparator s deve essere invariato, mentre A è controverso e B è covariante.

così ottengo errori come questo:

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] 
      ^

Vede qualche via d'uscita da questo o questo è solo uno di quei casi in cui "utilizzando generici Java a Scala fa male"?

risposta

12

Con l'aiuto di tipo-limiti è possibile effettuare le seguenti operazioni:

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

grazie. Che funzioni. Il codice non è ancora in esecuzione ma il tuo codice e la dichiarazione effettiva del Comparatore compilano salva e suono. Grazie mille. – Agl

+0

So che questa è una domanda completamente diversa, ma c'è una buona carta/tutorial/blog che copre i limiti di tipo e le varianti? Ho già letto su di esso ma si potrebbe sostenere che non ho imparato troppo da loro;) (d'altra parte, forse sono solo io. Quindi tutti li rileggo tutti di nuovo) – Agl

+2

Questo è abbastanza buono (anche se non è all'altezza -to-data - non ha informazioni su alcune funzionalità 2.8): http://programming-scala.labs.oreilly.com/ch12.html –

7

È possibile effettuare Extractor[A,B] estendono Comparator[A] utilizzando il @uncheckedVariance annotazione.

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 è sicuro qui perché Comparator avrebbero potuto essere definito come Comparator[-T]. C'era un discussion attorno al fare covariant Ordering per Scala 2.8 usando questa annotazione.

Modifica Vedere this question per ulteriori informazioni su @uncheckedVariance.

+0

e anche questo è bello. In realtà questa potrebbe essere la versione che finisce nel mio codice. . . non appena trovo il tempo di leggere quel thread che hai postato. Molte grazie! – Agl

Problemi correlati