В чем разница между протоколом и typealias в Swift?

Ответ

Протокол — это полноценный тип, определяющий контракт (требуемые свойства, методы, индексаторы) для других типов. Используется для полиморфизма и ограничений дженериков.

Typealias — это псевдоним для существующего именованного типа или сложного составного типа. Не создает новый тип, лишь дает ему альтернативное имя для удобства и ясности.

Сравнение:

Критерий Протокол Typealias
Назначение Определение требований (интерфейса) Создание синонима для типа
Реализация Требует реализации (conformance) Не требует реализации
Новый тип Да, это отдельный тип-протокол Нет, это лишь имя
Использование Полиморфизм, ограничения дженериков Упрощение сложных сигнатур, семантика

Примеры:

// PROTOCOL: Определяет требование
protocol Serializable {
    func serialize() -> Data
}
// Класс должен реализовать метод
class User: Serializable {
    func serialize() -> Data { /* ... */ }
}

// TYPEALIAS: Создает понятное имя для сложного типа
typealias UserID = Int
typealias CompletionHandler = (Result<Data, Error>) -> Void

func fetchUser(by id: UserID, completion: CompletionHandler) {
    // `UserID` яснее, чем просто `Int`
    // `CompletionHandler` компактнее полной сигнатуры
}

// Typealias также может ссылаться на протокол с ограничениями
typealias CodableData = Codable & Identifiable

Итог: Протокол — это инструмент проектирования архитектуры, typealias — инструмент для улучшения читаемости кода.

Ответ 18+ 🔞

Ну, смотри, тут у нас два таких понятия, которые новички постоянно путают, а потом ходят с глазами, как у Муму перед утоплением. Давай разжую, но без соплей.

Протокол — это, блядь, как устав в армии. Не нравится, сука? Иди нахуй, но если хочешь в наш клуб «Serializable», будь добр, реализуй метод serialize(). Это контракт, ёпта. Ты либо его выполняешь, либо ты никто. Используется, чтобы разные типы (классы, структуры) могли делать одно и то же, и чтобы дженерики не шарились с кем попало.

Typealias — это просто кличка, погоняло для уже существующего типа. Никакого нового типа не создаётся, это чисто для красоты и удобства. Взяли этого, блядь, (Result<Data, Error>) -> Void, который в глаза ебёт, и дали ему ласковое имя CompletionHandler. И все сразу счастливы.

Короче, табличка, чтобы не ебать мозг:

Критерий Протокол Typealias
Суть Устав. Требует исполнения. Кличка. Просто имя.
Надо реализовывать? Обязательно, а то получишь пизды. Нет, нихуя не надо.
Это новый тип? Да, отдельный тип-протокол. Нет, это тот же хуй, но в профиль.
Зачем? Архитектура, полиморфизм, ограничения. Читаемость, чтобы не писать хуйню в 50 символов.

Примеры, чтобы совсем пиздец:

// ПРОТОКОЛ: Вступаешь в клуб — соблюдай правила.
protocol Drunk {
    func drinkVodka() -> String
}
// Реализуешь, или иди нахуй.
class Russian: Drunk {
    func drinkVodka() -> String { return "За Путина!" }
}

// TYPEALIAS: Даём имена уродливым вещам.
typealias Rubles = Decimal // Не просто Decimal, а целых рубль, блядь!
typealias DrunkCallback = (String) -> Void // Читается же лучше, ёпта!

func payForVodka(amount: Rubles, onComplete: DrunkCallback) {
    // Видишь? Rubles и DrunkCallback. Красота, а не код.
}

// А ещё можно typealias'ом протокол с ограничением обозвать.
typealias FamousDrunk = Drunk & Celebrity // И пьёт, и по телеку мелькает!

Итог, блядь: Протокол — это про архитектуру и «как должно быть». Typealias — про удобство и «как не захлебнуться в этих ваших сигнатурах». Не путай, а то Герасим придёт и утопит твой код в ближайшем озере.