ПрограммированиеJunior iOS разработчик

Какие существуют виды коллекций в Swift, чем они различаются по внутренней реализации и когда какую коллекцию использовать?

Проходите собеседования с ИИ помощником Hintsage

Ответ.

В Swift есть три основные стандартные коллекции: Array, Set, и Dictionary. Каждая из них реализует разные интерфейсы, отличается внутренней структурой и предназначена для разных задач.

История вопроса:

В Swift коллекции спроектированы с упором на безопасность типов (type safety) и производительность, включая value semantics и копирование по принципу Copy-on-Write для Arrays/Set/Dictionary.

Проблема:

Часто начинающий разработчик использует только Array там, где корректнее было бы применить Set или Dictionary, что приводит к перерасходу памяти и снижению скорости доступа/поиска. Надо понимать различия.

Решение:

Array

Упорядоченная коллекция элементов, доступ по индексу, возможны дубликаты. Реализована обычно через динамический буфер.

Set

Неупорядоченная коллекция уникальных элементов (Hashable). Доступ по хешу — очень быстрый, дубли не допускаются.

Dictionary

Коллекция пар ключ-значение. Ключ должен быть Hashable. Доступ к значению по ключу (через хеш-таблицу).

Пример кода:

var arr: [Int] = [1, 2, 3, 4] var set: Set<Int> = [1, 2, 2, 3] var dict: [String: Int] = ["a": 1, "b": 2] // set == [1, 2, 3] — дубликаты отбрасываются

Ключевые особенности:

  • Array эффективен для доступа по индексу, поддерживает порядок, but доступ по значению линейный
  • Set быстр для поиска и проверки наличия элемента, хранит только уникальные Hashable значения
  • Dictionary оптимален для поиска по ключу (Hashable), не сохраняет порядок, но быстро ищет и изменяет значения

Вопросы с подвохом.

Можно ли использовать non-Hashable типы как элементы Set или Dictionary?

Нет. Для хранения в Set/Dictionary элемент должен быть Hashable (иметь уникальный хеш-идентификатор). В противном случае компилятор не даст создать коллекцию.

struct Point {} // Set<Point> вызовет ошибку, поскольку Point не Hashable

Является ли порядок хранения элементов Set таким же, как при их добавлении?

Нет. Set не гарантирует порядок — итерация может дать любой порядок. Если вам нужен порядок, используйте Array.

Что произойдет при попытке получить доступ к несуществующему ключу в Dictionary?

Dictionary вернет Optional. Будьте внимательны — попытка получить по несуществующему ключу выдаст nil, а не ошибку.

let val = dict["not exist"] // val — nil

Типовые ошибки и анти-паттерны

  • Использование Array для поиска уникального значения (лучше Set)
  • Использование Dictionary для хранения значений без необходимости поиска по ключу
  • Попытка использовать non-Hashable типы в качестве ключей/значений

Пример из жизни

Негативный кейс

Разработчик для уникального списка пользователей использует Array и ищет уникальность через contains. На больших списках — много времени на проверки.

Плюсы:

  • Простота реализации

Минусы:

  • Линейная сложность поиска, избыточное хранение дубликатов, большая нагрузка на память

Позитивный кейс

Тот же список реализован как Set. Проверка на наличие — мгновенная, уникальные значения гарантированы.

Плюсы:

  • Быстрый доступ, экономия памяти, исключение дублей

Минусы:

  • Нет гарантий порядка элементов