Что делает ключевое слово `mutating` в Swift?

«Что делает ключевое слово `mutating` в Swift?» — вопрос из категории Swift Core, который задают на 23% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Ключевое слово mutating в Swift позволяет методу экземпляра структуры или перечисления изменять свои свойства. По умолчанию методы value-типов (структур, перечислений) не могут менять self, так как они являются неизменяемыми по умолчанию.

Пример и синтаксис:

struct Point {
    var x: Int
    var y: Int

    // Без `mutating` этот метод не скомпилируется
    mutating func moveBy(x deltaX: Int, y deltaY: Int) {
        x += deltaX
        y += deltaY
        // Эквивалентно: self = Point(x: self.x + deltaX, y: self.y + deltaY)
    }
}

// Использование:
var myPoint = Point(x: 0, y: 0) // Должен быть `var`
myPoint.moveBy(x: 5, y: 3)
print(myPoint) // Point(x: 5, y: 3)

let constantPoint = Point(x: 0, y: 0)
// constantPoint.moveBy(x: 1, y: 1) // Ошибка компиляции: нельзя вызвать mutating метод на `let` константе

Ключевые правила:

  1. Только для value-типов: Применяется к struct и enum. В классах (class) не нужно, так как они — reference-типы.
  2. Требует переменную (var): mutating метод можно вызвать только для экземпляра, объявленного как var.
  3. Можно заменить весь self: Внутри mutating метода можно присвоить новый экземпляр свойству self.

Зачем это нужно? Это обеспечивает семантику value-типов: при изменении создается новая копия, что делает поведение предсказуемым и потокобезопасным.