Почему в методах классов Swift не нужен модификатор `mutating`?

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

Ответ

Ключевое слово mutating требуется только для value-типов (структур и перечислений), но не для ссылочных типов (классов). Это следствие фундаментального различия в их семантике.

Причина:

  • Классы (ссылочные типы): Передаются по ссылке. Метод, изменяющий свойство экземпляра, работает с исходным объектом в памяти. Изменение «на месте» не требует создания новой копии.
  • Структуры (value-типы): Передаются по значению (копируются). Ключевое слово mutating явно указывает компилятору, что метод собирается изменить уникальную копию self, и для этого необходимо сделать текущий экземпляр изменяемым (var).

Пример сравнения:

// КЛАСС - mutating не нужен
class PersonClass {
    var name: String
    init(name: String) { self.name = name }
    func changeName(to newName: String) {
        name = newName // Изменяет исходный объект
    }
}

// СТРУКТУРА - mutating обязателен
struct PersonStruct {
    var name: String
    mutating func changeName(to newName: String) {
        name = newName // Изменяет локальную копию self
    }
}

var person = PersonStruct(name: "Alex")
person.changeName(to: "John") // Работает только если `person` объявлен как `var`

Практическое следствие: Для вызова mutating метода структуры, экземпляр должен быть объявлен с var, а не с let.