Какие виды коллекций есть в Swift
Что проверяют
Знаете ли вы три основные коллекции и понимаете ли, что даёт копирование при записи.
Как отвечать
Основных три, и все они значимые типы:
Array: упорядоченная последовательность с дубликатами. Доступ по индексу за постоянное время, добавление в конец амортизированно постоянное, вставка в середину линейная;Set: неупорядоченное множество уникальных элементов. Требует соответствия протоколу хеширования. Проверка вхождения за постоянное время, есть операции объединения, пересечения и разности;Dictionary: пары ключ и значение, ключи хешируемые, доступ за постоянное время, порядок не гарантирован.
Главная особенность, которую и хотят услышать: они значимые, но копирование дешёвое благодаря копированию при записи. При присваивании копируется только заголовок, а общий буфер остаётся один. Настоящее копирование происходит лишь при первой попытке изменения, и только если на буфер ссылается кто-то ещё. Проверяется это функцией уникальности ссылки, и её же используют при написании собственных структур с внутренним буфером.
Отсюда практическое следствие: передавать массив в функцию дёшево, а вот изменять его внутри цикла, держа вторую ссылку рядом, дорого, потому что копирование сработает.
Что стоит добавить:
- иерархия протоколов: последовательность, коллекция, двунаправленная, с произвольным доступом. Именно она объясняет, почему у строки индексация не за постоянное время:
Stringэто коллекция символов переменной ширины, и произвольного доступа у неё нет; - срез массива не копирует данные, но удерживает исходный буфер целиком. Сохранили срез от большого массива, и весь массив остался в памяти. Лечится явным созданием нового массива;
reserveCapacityпри известном размере убирает перевыделения;- в отдельном пакете коллекций есть дек, упорядоченное множество и упорядоченный словарь, которых нет в стандартной библиотеке.
Где спотыкаются
Считают копирование массива дорогим всегда.
Хранят срез и удивляются расходу памяти.
Ждут от словаря стабильного порядка обхода.
Не знают, почему нельзя обратиться к символу строки по числовому индексу.