Разница между двумя определениями классов относительно контравариантного типа?

class Contravariant[-T](val other:T)

ошибка: контравариантный тип T встречается в ковариантной позиции в типе T значения other

Однако это удается

class MMX[-T](x:T)

В чем разница?

Спасибо


person PheniX Tylor    schedule 05.10.2020    source источник
comment
Потому что, если префикс аргумента с val, тогда он становится общедоступным полем, и, как таковой, геттер создается с использованием T в качестве возвращаемого типа, что невозможно, потому что T имеет значение < i> контравариантный.   -  person Luis Miguel Mejía Suárez    schedule 05.10.2020


Ответы (1)


Как сказал , в в первом примере other - это поле, и поля не могут быть контравариантными (как указал Дмитрий Митин, а не поля с модификатор private[this] или protected[this]), хотя они могут быть ковариантными. Рассмотрим этот пример, если ваш первый пример сработал:

class Contravariant[-T](val other: T)

val stringList = List[Contravariant[String]](new Contravariant[Any](1))
val string: String = stringList.head.other //This can't work, because 1 is not a String

Здесь вы можете увидеть, что происходит (я использовал @uncheckedVariance, чтобы это работало).

Во втором примере x - это просто параметр вашего конструктора, а параметры могут быть контравариантными, поэтому он работает.

person user    schedule 05.10.2020
comment
Поля не могут быть контравариантными Поля, отличные от private[this] или protected[this]. - person Dmytro Mitin; 05.10.2020
comment
@DmytroMitin Я не думал об этом, так как я никогда не использовал контравариантные поля. Я отредактировал его сейчас в ответе, надеюсь, на этот раз он будет правильным. - person user; 06.10.2020
comment
Что ж, это больше о доступе, чем о возможности переопределения. - person Dmytro Mitin; 06.10.2020
comment
Я удалил часть переопределения. - person user; 06.10.2020