Ответ
Ключевое слово 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.