Ключевое слово inout в Swift позволяет функции изменять значение переданного параметра непосредственно (по ссылке), а не работать с копией. Это аналог pass-by-reference в некоторых других языках.
Пример:
func increment(_ value: inout Int) { value += 1 } var x = 10 increment(&x) // Теперь x == 11
var), нельзя передать let.Вопрос: Можно ли передавать свойство структуры в функцию с inout-параметром, если структура при этом используется как часть другого объекта?
Ответ: Нет, потому что Swift запрещает одновременный доступ к одному и тому же свойству в рамках одной инструкции (Exclusive Access to Memory), чтобы избежать race condition и неопределённого поведения. Пример:
struct Point { var x: Int var y: Int } var p = Point(x: 1, y: 2) increment(&p.x) // ok increment(&p.y) // ok // increment(&p.x, &p.x) // вызовет ошибку
История
В одном проекте разработчик попытался передать одну и ту же переменную одновременно в два параметра-функции с модификатором inout, что привело к ошибке компиляции. Это вынудило пересмотреть архитектуру функции, разбив изменения на два шага.
История
Реализатор изменял массив через inout-параметр внутри цикла, что приводило к непредвиденным результатам, т.к. Swift копирует содержимое при передаче, а изменения не синхронизировались между циклами.
История
Разработчик ожидал, что inout-параметры будут всегда работать "по ссылке", но наткнулся на copy-in/copy-out семантику при работе с классами и структурами, из-за чего не все изменения сохранялись, если изменялись вложенные объекты структур.