Страницы

Поиск по вопросам

пятница, 5 октября 2018 г.

Правило контравариантности в Scala

Скомпилируется ли следующий код?
class GenericCellMut[-T](var x:T)
Если да, то почему? Если нет, то почему, и как сделать так, чтобы скомпилировался?
Он, естествено, не компилируется. Остается два вопроса - почему и что изменить, чтобы скомпилировался.
Пробовал читать статьи про ко/контравариантности, но так для себя ничего и не вынес.


Ответ

Насколько мне известно, Scala проверяет, что все контравариантные типы встречаются только на позициях аргументов, а все ковариантные типы -- на позициях возвращаемых значений.
Ваше выражение не проходит проверку из-за того, что наличие поля x подразумевает то, что его можно получить из этого класса, т.е. использовать в ковариантной позиции. Из-за этого не поможет и сделать поле x константным.

Насколько я понимаю, вы хотите сделать изменяемую ячейку.
Мне не очень понятно, для чего может потребоваться изменяемая ячейка со свойством контравариантности. Единственное, что я могу предложить для того, чтобы этот пример компилировался -- это написать следующий код:
class GenericCellMut[+T](val x:T)
Это будет неизменяемая ячейка со свойством ковариантности (замечу, что у неё теперь не очень подходящее название). Сделать поле изменяемым нельзя, так как это будет требовать наличия метода установки значения x, что, в свою очередь, требует поставить тип T в контравариантную позицию.
Если вы хотите иметь изменяемую ячейку, то придётся сделать её инвариантной:
class GenericCellMut[T](val x:T)

Комментариев нет:

Отправить комментарий