Ответ
Swift не генерирует автоматический memberwise инициализатор для классов из-за их наследуемой природы и требований безопасности инициализации.
Основные причины:
- Наследование — класс должен гарантировать корректную инициализацию не только своих свойств, но и унаследованных от суперкласса.
- Безопасность — компилятор требует явного контроля над процессом инициализации для предотвращения частично инициализированных объектов.
- Гибкость — классы могут иметь вычисляемые свойства, наблюдатели или требовать дополнительной логики при инициализации.
Три способа обеспечить инициализацию класса:
- Назначение значений по умолчанию всем stored-свойствам
- Реализация собственного инициализатора
- Наследование инициализатора от суперкласса
Пример:
class Person {
var name: String
var age: Int
// Должны написать явно — Swift не сгенерирует init(name:age:)
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
// Для сравнения — структура получает memberwise инициализатор автоматически
struct Point {
var x: Double
var y: Double
// Имеет init(x:y:) по умолчанию
}
Контраст со структурами: Структуры получают memberwise инициализатор, так как они не поддерживают наследование и имеют более простую семантику копирования.
Ответ 18+ 🔞
Ага, слушай, вот это вообще классика, блядь! Сидишь такой, переписываешь код со структуры на класс, и тут — пиздец! Куда делся мой красивый init(name: age:)? А его нет, сука!
Swift, этот хитрожопый компилятор, просто берёт и НЕ ГЕНЕРИРУЕТ автоматический инициализатор для классов. Вообще. Ни хуя. А знаешь почему? Ну, держись.
Вот нахуй так происходит:
-
Наследование, блядь! Это же не какая-то тупая структура, которая сама по себе. Класс — он может от кого-то родиться. И компилятору надо быть на 146% уверенным, что когда ты создаёшь объект, там всё проинициализировано правильно: и твои свеженаписанные свойства, и всё, что там наворочено у родителя. А автоматический инициализатор про это нихуя не знает, вот его и нет.
-
Безопасность, ёпта! Чтобы не получилось так, что у тебя объект уже в памяти болтается, а половина свойств в нём —
nilили какая-то хуйня. Swift не любит неопределённость, как кот лоток грязный. -
Гибкость, вротберунчик! В классе же может быть не просто
var name: String. Там может быть вычисляемое свойство, там могут быть наблюдателиdidSet, которые при инициализации нахуй не нужны, или тебе перед сохранением значения надо его через сито пропустить. Куда это впихнуть в автосгенерированный инит?
Ну и что делать-то, если очень хочется? Варианты, как всегда, есть:
- По-дедовски: Всем свойствам значения по умолчанию присвоить.
var name: String = "". Готово, можноPerson()создавать. Но это, бля, не всегда окей. - Взять и написать самому, блядь! Да, вот так вот, руками. Как взрослый. Объявляешь
init(name: String, age: Int)и внутри раздаёшьself.name = name. Скучно, зато надёжно. - Наследовать от предка. Если у родительского класса есть подходящий
init, и ты все свои свойства по дефолту проинициализировал — можешь его унаследовать.
Смотри, вот тебе наглядный пиздец, прости, пример:
class Person {
var name: String
var age: Int
// Бля, придётся это писать САМОМУ! Swift за тебя это не сделает, ленивая жопа!
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
// А теперь смотри на эту мартышку-структуру! Ей всё похуй!
struct Point {
var x: Double
var y: Double
// А здесь init(x:y:) УЖЕ ЕСТЬ, ПОДАРОЧКОМ! Бесплатно, сука!
// Потому что структура — она простая, без этих ваших наследований.
}
Вот и весь сказ, блядь. Классы — они сложные, ответственные. За них надо думать. А структуры — как весёлые туристы, им всё включено. Выбирай, что тебе больше по душе: власть и ответственность или бесплатный сыр, понимаешь?