Что произойдёт при создании словаря из последовательности пар через инициализатор, требующий уникальных ключей, если один ключ встретится дважды?
Инициализатор Dictionary(uniqueKeysWithValues:) завершится ошибкой предусловия во время выполнения, если последовательность содержит повторяющийся ключ. Он не выберет последнее значение, не вернёт nil и не сообщит об ошибке через throws.
Этот инициализатор подходит только тогда, когда уникальность ключей гарантирована контрактом входных данных. Если повторы допустимы, нужно явно выбрать стратегию их обработки.
Словарь хранит не более одного значения для каждого ключа, поэтому при построении из последовательности пар возникает конфликт: какое значение сохранить при повторе. API Swift разделяет создание словаря с жёстким требованием уникальности и создание словаря с явным правилом разрешения конфликтов.
Такое разделение предотвращает случайную потерю данных из-за неявного перезаписывания значения. Политика обработки повторов становится частью вызова, а не скрытым побочным эффектом.
Если источник данных ошибочно содержит два значения с одним ключом, использование uniqueKeysWithValues: приводит к аварийному завершению приложения. Это особенно опасно для данных из сети, файлов или пользовательского ввода, где уникальность нельзя считать гарантированной.
Автоматическая замена значения может быть не менее опасной: приложение продолжит работу, но незаметно потеряет одну из записей. Поэтому важно отличать нарушение инварианта от штатной ситуации, для которой заранее определено правило выбора.
Dictionary(uniqueKeysWithValues:) обходит пары и добавляет каждую по её ключу. При обнаружении ключа, который уже присутствует в словаре, Swift нарушает предусловие и вызывает runtime trap.
Если нужно выбрать одно из значений, применяется инициализатор Dictionary(_:uniquingKeysWith:). Его замыкание получает значения, столкнувшиеся по одному ключу, и возвращает то, которое будет сохранено.
В примере при повторе ключа "ru" сохраняется новое значение. Если выбрать первое значение, замыкание должно вернуть первый аргумент; если требуется сохранить все значения, лучше использовать Dictionary(grouping:by:), результатом которого будут массивы значений для каждого ключа.
Важно, что Hashable-ключи сравниваются не только по совпадению хешей: одинаковый хеш ещё не означает равенство. Словарь использует хеш для поиска кандидатов, а окончательное решение принимает по равенству ключей.
Сервис загружает список настроек локализации, где ключом является код языка. В нормальном ответе сервера каждый код должен встречаться один раз, поэтому молчаливое сохранение последнего значения может скрыть дефект данных.
Возможны три варианта:
uniqueKeysWithValues: — строго проверяет контракт, но аварийно завершает приложение при ошибке входных данных;uniquingKeysWith: — приложение продолжает работу, однако выбранная стратегия может потерять одну из записей;Dictionary(grouping:by:) — сохраняет все записи, но меняет модель данных и требует последующей обработки массива значений.Для внешних данных практичнее сначала проверить дубликаты и вернуть доменную ошибку, а словарь создавать только после успешной проверки. Если бизнес-логика допускает несколько настроек одного языка, следует сразу использовать группировку; если приоритет имеет последняя запись, нужно явно указать соответствующее замыкание объединения.
Нет. uniqueKeysWithValues: специально не задаёт политику перезаписи. Повтор ключа означает нарушение предусловия, поэтому выполнение завершается аварийно. Для перезаписи нужно использовать uniquingKeysWith: и явно вернуть первое или второе значение.
Будет создан пустой словарь. Ошибка возникает не из-за отсутствия элементов, а только при нарушении требования уникальности ключей. Тип ключа и значения при этом всё равно должен быть корректно выведен или задан компилятором.
Следует использовать группировку: каждому ключу сопоставляется массив всех связанных значений. Это отличается от uniquingKeysWith:, где в словаре остаётся только один результат объединения и остальные значения могут быть отброшены.
Группировка особенно уместна для тегов, записей журнала или товаров, объединённых по категории. Она сохраняет информацию, но требует учитывать порядок значений в массиве и дополнительную обработку при чтении.