Может ли новый массив, полученный через map, изменить состояние объектов из исходного массива?
Да, если элементы массива — экземпляры классов. map создаёт новый массив, но обычно переносит в него те же ссылки на объекты, поэтому изменение свойства объекта через элемент результата будет видно и через исходный массив. Для структур такое поведение отличается: изменяется копия значения, а не исходный элемент.
Функциональные операции коллекций разделяют преобразование контейнера и поведение самих элементов. Такой подход удобен для построения новых коллекций, но не означает глубокого копирования каждого объекта.
В Swift это особенно важно из-за различия между значимыми типами — структурами и перечислениями — и ссылочными типами — классами. Коллекция является самостоятельным значением, однако её элементы могут содержать ссылки на общие объекты.
Разработчик видит новый массив после map и может ошибочно заключить, что все его элементы независимы от элементов исходного массива. Для классов это приведёт к неожиданным побочным эффектам: изменение объекта во время преобразования или после него изменит состояние, доступное из обеих коллекций.
Обратная ошибка тоже возможна: ожидание, что преобразование структуры изменит исходный массив, обычно неверно. Поэтому нужно отдельно анализировать копирование контейнера и семантику типа его элементов.
map применяет замыкание к каждому элементу и собирает возвращённые значения в новую коллекцию. Если замыкание возвращает экземпляр класса, копируется ссылка на него, а не состояние объекта.
В примере source и result — разные массивы, но их элементы указывают на один экземпляр User. Поэтому присваивание внутри замыкания является побочным эффектом и меняет объект, видимый из обеих коллекций.
Для структуры результат обычно независим на уровне самого значения: изменение свойства локальной копии не меняет исходный элемент. Однако структура может содержать ссылочное поле, например экземпляр класса, и тогда вложенный объект всё равно останется общим.
Если нужна независимая модель, следует явно создавать копии объектов или преобразовывать их в неизменяемые структуры. Это требует дополнительных затрат по времени и памяти, зато устраняет совместное состояние. Если же объекты намеренно разделяются, нужно избегать мутаций внутри map и использовать его только для чистого преобразования.
В слое отображения есть массив объектов User, а экрану требуется массив подготовленных представлений. Вариант с изменением имени пользователя внутри map прост, но опасен: исходная модель будет изменена во время подготовки данных.
Можно вернуть те же объекты без мутации — это дёшево и сохраняет общую идентичность, но экран и модель останутся связаны. Можно создать отдельные структуры представления — это требует явного преобразования, зато делает границу данных безопасной и предсказуемой.
Практичнее выбрать второй вариант: сформировать неизменяемые структуры с нужными полями. В результате подготовка экрана не меняет модель, а изменения состояния становятся локальными и проще контролируются.
Нет. map копирует результат, возвращённый замыканием. Для класса этим результатом обычно является ссылка на тот же объект. Новая экземплярная копия появится только при явном создании нового объекта или использовании специального механизма копирования.
Изменение самой структуры через значение, полученное в замыкании, не изменяет исходный элемент: структура имеет семантику значения. Но если структура содержит ссылку на класс, мутация объекта по этой ссылке будет видна из исходной структуры и результата.
Нет. map не устанавливает защиту от дальнейших изменений и не меняет правила доступа к исходной коллекции. Он лишь создаёт результат преобразования; общие ссылочные элементы могут продолжать изменяться через любую доступную ссылку.