Как правильно переопределить operator [] из MapBase

#dart

#dart

Вопрос:

Я создал простой класс extending MapBase<String, String> . Все выглядит хорошо, кроме operator [] переопределения. Это код:

 class MyMap extends MapBase<String, String> {

  Map<String, String> _map = {};

  @override
  Iterable<String> get keys => _map.keys;

  @override
  String remove(Object key) => _map.remove(key);

  @override
  void clear() => _map.clear();

  @override
  operator []= (String key, String value) => _map[key] = value;

  @override
  String operator [] (String key) => _map[key];
}
  

@override operator [] Результатом является следующая ошибка:

 error: 'MyMap.[]' ('(String) → String') isn't a valid override of 'Map.[]' ('(Object) → String'). (invalid_override at [joap] libapiapi_query.dart:43)ˋ
error: 'MyMap.[]' ('(String) → String') isn't a valid override of 'MapMixin.[]' ('(Object) → String'). (invalid_override at [joap] libapiapi_query.dart:43)
  

Я нахожу это странным, потому @override operator []= что не показывает эту ошибку. Удаление String типа из key параметра решает проблему.

Что я здесь делаю не так?

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

1. Не уверен, почему обратные тики работают не так, как ожидалось. Извините за это.

2. Я исправил форматирование. ˋ Символ (U 02CB) не является ` символом (U 0060). (Это гомоглифы .)

3. Спасибо. Попытаюсь выяснить, что не так с моими настройками клавиатуры RDP, и исправить это.

Ответ №1:

Подпись для вашего operator[] переопределения не соответствует базовой подписи.

Map operator[] принимает Object аргумент, а не тип . Key (Напротив, operator[]= принимает Key тип в качестве своего аргумента.)

(Я нашел это удивительным, но для этого есть обоснование.)

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

1. Спасибо за ответ, хотя у меня возникли проблемы с пониманием этого обоснования. Но это потому, что я не такой быстрый и, вероятно, мне нужно прочитать это еще пару раз 🙂

2. @Pieter-JandeVries По сути, обоснование заключается в том, что Java делает нечто подобное, а именно: если у вас есть коллекция яблок, то если вы спросите, содержит ли она апельсин, ответ будет «нет» (потому что это не так) вместо генерации ошибки. То есть задавать глупые вопросы — это не ошибка.

3. Еще раз спасибо Джеймсу. Сам факт, что Java делает это подобным образом, на самом деле не является веской причиной. Это также не объясняет, почему key параметр для operator []= обрабатывается иначе, чем для operator [] . В данном конкретном случае я явно расширяю MapBase<String, String> , намереваясь объявить строгий интерфейс, принимающий только строки в качестве допустимых значений ключа. Итак, я все еще не понимаю, почему моя реализация не принимает String как key . В конце концов, у меня есть коллекция яблок, и я просто запрашиваю конкретное яблоко. Или я все еще чего-то здесь не хватает?

4. operator[]= необходимо принять Key , потому что попытка вставить ключ неправильного типа нарушит работу контейнера. Контейнер, объявленный как содержащий только яблоки, не может содержать апельсины, но ответ на вопрос, содержит ли этот контейнер апельсин, всегда «нет». (Обратите внимание, что я не согласен с operator[] принятием Object .) Что касается того, почему ваша реализация не может работать, это потому, что язык не поддерживает перегруженные методы, поэтому переопределения должны точно соответствовать сигнатуре базового метода.

5. Ага! Я не знал о перегрузках не поддерживаемых операторов. Это позор, но, по крайней мере, теперь это имеет смысл для меня. Спасибо за вашу помощь и терпение.