2010-09-15 5 views
12

Tengo un rasgo que se parece a esto (algunos más información se puede encontrar en this related question by myself aunque no creo, se necesita para esta pregunta)covariante Typeparameter en Scala necesita ser invariantes en la interfaz Java

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

para utilizar esto en un marco de java existente me gustaría que esta Extractor que o bien tienen una función que devuelve un Comparator[B] (siendo java.util.Comparator) o incluso mejor extender Comparator[A]. Ahora eso plantea un problema porque el parámetro de tipo Comparator s debe ser invariable, mientras que A es contravariante y B es covariante.

Así que tengo errores como este:

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

¿Ves alguna forma de salir de este o esto es sólo uno de esos casos en los que "utilizando genéricos de Java en Scala duele"?

Respuesta

12

Con ayuda de tipo-límites que es posible hacer lo siguiente:

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

gracias. Eso funciona. El código aún no se está ejecutando, pero su código y la declaración efectiva del comparador compilan guardado y sonido. Muchas gracias. – Agl

+0

Sé que esta es una pregunta completamente diferente, pero ¿hay un buen documento/tutorial/blog que cubra los límites de tipo y las variantes? Ya lo leí pero se podría argumentar que no aprendí demasiado de ellos;) (por otro lado, tal vez sea solo yo. Así que todos los volvieron a leer) – Agl

+2

Este es bastante bueno (aunque no está bien) -hasta la fecha -no tiene información sobre algunas características 2.8): http://programming-scala.labs.oreilly.com/ch12.html –

7

Puede hacer Extractor[A,B] extienden Comparator[A] mediante el uso de la anotación @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 es seguro aquí porque Comparator podrían haberse definido como Comparator[-T]. Hubo un discussion alrededor de hacer Ordering covariante para Scala 2.8 usando esta anotación.

Editar Ver this question para más información sobre @uncheckedVariance.

+0

uh, eso también es bueno. En realidad, esta podría ser la versión que termina en mi código. . . tan pronto como encuentre el tiempo para leer ese hilo que publicó. ¡Muchas gracias! – Agl

Cuestiones relacionadas