#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. Ага! Я не знал о перегрузках не поддерживаемых операторов. Это позор, но, по крайней мере, теперь это имеет смысл для меня. Спасибо за вашу помощь и терпение.