Что происходит при передаче значимого типа в Swift в функцию или при присваивании
Что проверяют
Понимаете ли вы семантику значений глубже фразы «структуры копируются», и знаете ли две вещи, которые её усложняют: копирование при записи и ссылочные поля внутри структуры.
Как отвечать
При присваивании и при передаче в функцию значимый тип копируется, оригинал изменить нельзя. Параметр функции к тому же неизменяем: это константа, присвоить ей что-то внутри функции не выйдет, для изменения на месте нужен inout.
struct Point { var x = 0 }
var a = Point()
var b = a
b.x = 5 // a.x всё ещё 0
func move(_ p: inout Point) { p.x += 1 }
move(&a) // теперь a.x равен 1Дальше важная поправка. Буквальное копирование на каждом присваивании было бы дорогим, поэтому стандартные коллекции и строки используют копирование при записи: пока никто не пишет, буфер общий, а настоящее копирование случается в момент первой записи, если ссылок на буфер больше одной. Поэтому передать большой массив в функцию дёшево, а изменить его копию уже нет. Свой тип так себя не ведёт автоматически, это делают руками через isKnownUniquelyReferenced.
Вторая поправка: копия структуры поверхностная. Если внутри лежит поле ссылочного типа, копируется ссылка, и обе структуры смотрят на один объект. Изменение через него увидят обе.
Где спотыкаются
Считают, что значимый тип автоматически безопасен в многопоточности. Он безопасен, только если целиком состоит из значений. Структура с классом внутри разделяет состояние между потоками ровно так же, как сам класс.
Второе: говорят, что структуры всегда лежат на стеке, а классы в куче. Для локальной структуры из простых полей обычно так и есть, но структура с полем-коллекцией держит буфер в куче, а захваченная замыканием уезжает туда же. Размещение решает компилятор, а не вид типа.
Третье: пробуют менять свойство структуры внутри её обычного метода и получают ошибку компиляции. Метод, меняющий поля значимого типа, помечают mutating, и позвать его у константы уже нельзя.