Вы не можете иметь переменную ковариантного типа.Var означает наличие, среди прочего, публичного def v_=(newV: T)
, так что он заставляет T появляться в качестве обычного аргумента, который является противоположной позицией.Так что вы должны либо
- отказаться от ковариации и объявить C [T], а не C [+ T]
- make va val
Быть немногоБолее подробно о части «почему» в вашем вопросе. Делая T ковариантным параметром с + T, вы заявляете, что хотите, чтобы C [B] был подтипом C [A], если B является подтипом A. Это означает, что выwant to allow:
val cb: C[B] = new C[B]
val ca : C[A] = cb
Чтобы это звучало, компилятор ограничивает место, где T может появиться в C. Для краткости и с небольшими упрощениями v не может появляться как параметр подпрограммы (или как типиз вар).В противном случае, после того, как вы инициализировали cb и ca, как описано выше, вы можете
ca.v = new A
Это будет разрешено, так как ca
должен быть C[A]
, поэтому его переменная v
имеет типA
.Однако, поскольку C ковариантен в T, ca
может (и имеет в этом примере) ссылаться на экземпляр C[B]
.Если бы это назначение было разрешено, тогда вы могли бы
val vInCb: B = cb.v
быть уверенным, что это даст вам B .Однако вы просто помещаете туда A через ссылку ca
.Эта ситуация должна быть запрещена, и это, запрещая параметр ковариантного типа T как тип переменной.