class C [+T] { var v : T = _ }
cómo inicializar la variable covariante?
error del compilador: Tipo covariante T se produce en la posición contravariante de tipo T de valor VALUE_ =
por qué? ¿Cómo puedo arreglarlo?
class C [+T] { var v : T = _ }
cómo inicializar la variable covariante?
error del compilador: Tipo covariante T se produce en la posición contravariante de tipo T de valor VALUE_ =
por qué? ¿Cómo puedo arreglarlo?
No puede tener var de tipo covariante. Una var equivale a tener, entre otras cosas, un def v_=(newV: T)
público, por lo que hace que T aparezca como un argumento de rutina, que es una posición contravariante. Por lo que debe o bien
Para ser un poco más detallado en el "por qué" parte de su pregunta, al hacer T es el parámetro covariante con + T, declara que quiere que C [B] sea un subtipo de C [A] si B es un subtipo de A. Esto significa que desea permitir:
val cb: C[B] = new C[B]
val ca : C[A] = cb
Para hace que suene, el compilador restringe dónde T puede aparecer en C. Para hacerlo breve y con pequeñas simplificaciones, v no puede aparecer como parámetro de una rutina (o como el tipo de una var). De lo contrario, después de haber inicializado CB y CA como se describió anteriormente que coulddo
ca.v = new A
Esto se permitiría, como ca
se supone que es un C[A]
, por lo que su variable v
es de tipo A
. Sin embargo, como C es covariante en T, ca
puede (y lo hace en el ejemplo) hacer referencia a una instancia C[B]
. Se permitiría esta asignación, entonces podría hacer
val vInCb: B = cb.v
seguros de que esto le da una B. Sin embargo, usted acaba de poner un A allí a través de la referencia ca
. Esta situación debe estar prohibida, y lo es, al prohibir el parámetro de tipo covariante T como el tipo de una var.
Tienes que hacerlo un val
. A var
siempre tiene un método setter donde el tipo aparece en una posición contravariante.
Se puede declarar como private[this]
:
class C [+T] { private[this] var v : T = _ }
Cualquier uso intenta que este ámbito no permite que sería insegura con un co-variante T
.
Hay una tercera opción ... –
Muchas gracias Daniel, había escrito una tercera variante con privacidad y la quité después de las pruebas, me había olvidado de esto [esto] –