Полное избавление от ковариации, конечно, было бы неразумно и не допускается.Учитывая m: Map[A, String]
и v : Any
, вы можете сделать val mm : Map[A, Any] = m + v
.Это то, что говорит определение Map
, и все разработчики должны следовать.Ваш класс может быть инвариантным, но он должен реализовывать полный ковариантный интерфейс Map.
Теперь переопределение +
для выдачи ошибки - это отдельная история (пока не очень хорошая).Проблема с вашим новым методом +
заключается в том, что после стирания обобщенных элементов он имеет ту же сигнатуру, что и другой метод +
.Есть хитрость: добавьте неявный параметр, чтобы у вас было два параметра в сигнатуре, что отличает его от первого.
def +(kv : (A,B))(implicit useless: A <:< A) : MyMap[A,B]
(не имеет значения, какой неявный параметр вы ищете, пока он найден. implicit useless: Ordering[String]
работает так же хорошо)
Делая это, выесть обычная проблема с перегрузкой.Если вы добавите B без компилятора, который знает, что это так, будет вызван ошибочный метод.Там может быть лучше выполнить проверку типа, чтобы экземпляры B принимались как угодно.Для этого потребуется получить Манифест [B] на вашей карте.