В каких случаях класс в Swift не получает стандартный инициализатор?

Ответ

Класс в Swift не получает автоматически сгенерированный memberwise инициализатор, в отличие от структур. Это происходит, если:

  1. Свойства класса не имеют значений по умолчанию.
  2. Суперкласс не предоставляет доступный инициализатор (в случае наследования).
  3. Класс определяет собственный designated инициализатор — это отключает наследование инициализаторов.

Пример:

class Person {
    var name: String // Нет значения по умолчанию
    var age: Int     // Нет значения по умолчанию
    // Без явного инициализатора компиляция не удастся
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

Решение:

  • Задать значения по умолчанию свойствам (var name: String = "").
  • Реализовать собственные designated инициализаторы.
  • Для структур memberwise инициализатор предоставляется автоматически.

Ответ 18+ 🔞

А, слушай, вот этот ваш Swift, он же иногда такой подлянкой прикидывается! Смотри, объявляешь ты класс, а он тебе — ни фига, ни memberwise инициализатора! А в структурах-то, сука, всё как по маслу — нате вам, получайте, хуй с горой свойств, инициализатор уже готовенький!

А с классами — ёпта, цирк начинается. Почему? Да потому что класс — он, блядь, сложнее, у него там наследственность, всякие суперклассы, и компилятор не хочет, чтобы ты, распиздяй, накосячил.

Вот три главные причины, почему твой класс остаётся голым, как младенец, без инициализатора:

  1. Свойства без дефолтных значений. Ну ты ж не сказал, чем их инициализировать, блядь! var name: String — и что с этой хуйней делать? Компилятор в ступоре: "Э, сабака, сука, э бошка думай! Откуда я знаю, какое имя по умолчанию? 'Вася' или 'Герасим'?"
  2. Наследование от какого-нибудь ёбанного суперкласса. Если у родителя нет доступного инициализатора, то и тебе, сынок, нихуя не светит.
  3. Ты сам, умник, написал designated инициализатор. Всё, приехали! Как только ты заявил init(...) { ... }, компилятор говорит: "А, ну раз ты такой самостоятельный, хуле я тебе буду мешать? Разбирайся сам, я пошёл". И наследование инициализаторов отключается нахуй.

Вот смотри, классический пример, который в компиляторе не взлетит:

class Person {
    var name: String // Ни хуя себе значение по умолчанию!
    var age: Int     // И тут нихуя!
    // Без явного инициализатора тут будет пиздец и ошибка компиляции
    init(name: String, age: Int) { // Вот, пришлось самому горбатиться
        self.name = name
        self.age = age
    }
}

И что делать-то, спросишь? Варианты, блядь, есть!

  • Задай значения по умолчанию, ленивая жопа! var name: String = "" и var age: Int = 0. Тогда компилятор успокоится и, возможно, что-то сгенерирует (но не факт, с классами всё сложно, ёпта).
  • Пиши свои инициализаторы вручную. Это самый надёжный путь, тут уж не обосрёшься.
  • Используй структуры (struct), если можешь. Вот там — да, там тебе сразу memberwise инициализатор в рот запихают, и никаких вопросов. Но это если тебе наследование не нужно, конечно.

Короче, запомни: класс в Swift — это не структура, тут за тебя нихуя не сделают, если ты сам не позаботишься. Волнение, блядь, на нуле, когда это понимаешь!