0Pricing
Swift Academy · Урок

Расширения протоколов и расширения типов

Сравните расширения протоколов (добавляют реализации по умолчанию к протоколу, в том числе условно) с расширениями типов (добавляют API к одному конкретному типу). Разберитесь с поведением диспетчеризации и ограничениями.

«Расширения протоколов и расширения типов» — бесплатный урок Swift Academy на CoddyKit. Это урок 2 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 3 уроков всего.

Обзор

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

Протокол и соответствие

Протоколы объявляют требования. Типы соответствуют протоколам, реализуя эти требования.

protocol Greeter {
    func greet() -> String
}
struct Person: Greeter {
    var name: String
    func greet() -> String { "Hi, I'm \\(name)" }  // concrete requirement impl
}
print(Person(name: "Ada").greet())

Реализации по умолчанию через расширение протокола

Расширение протокола может предоставлять реализации по умолчанию, используемые всеми соответствующими типами, если они не предоставляют собственные реализации.

protocol Describable {
    func describe() -> String
}
extension Describable {
    // default for ALL conformers until they override
    func describe() -> String { "No description" }
}

struct Car: Describable { }             // uses default
struct Book: Describable {
    func describe() -> String { "A book" } // custom override
}
print(Car().describe(), Book().describe())

Программные интерфейсы расширения типа

Расширения типа добавляют методы и вычисляемые свойства одному конкретному типу. Они не добавляют хранимые свойства.

struct Point { var x: Int; var y: Int }

extension Point {
    // add helper just to Point
    var lengthSquared: Int { x*x + y*y }
    func moved(dx: Int, dy: Int) -> Point { Point(x: x+dx, y: y+dy) }
}
let p = Point(x: 2, y: 3)
print(p.lengthSquared, p.moved(dx: 1, dy: -1))

Условные расширения

Добавляйте поведение только к некоторым соответствующим типам, используя условие в расширении протокола.

protocol Summable { }
extension Int: Summable { }
extension Array where Element: Summable {
    // only for arrays whose elements conform to Summable
    func joinedCount() -> Int { self.count }
}
print([1,2,3].joinedCount())   // works (Int conforms)
 // print(["a","b"].joinedCount()) // not available

Поведение диспетчеризации: обзор

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

protocol Speaker { func speak() -> String }
extension Speaker { func speak() -> String { "default" } }

struct Cat: Speaker { }
struct Dog: Speaker {
    func speak() -> String { "woof" } // requirement impl overrides default
}

let s1: Speaker = Cat()
let s2: Speaker = Dog()
print(s1.speak()) // "default" (uses default impl)
print(s2.speak()) // "woof" (Dog provides requirement impl)

let c = Cat()
print(c.speak())  // "default" via extension on protocol

Расширение протокола и расширение типа

Быстрая проверка: в чём ключевое различие?

Повторение

Повторение: используйте расширения протоколов для повторно используемых реализаций по умолчанию, при необходимости с условиями. Используйте расширения типов, чтобы расширять один тип. Помните о диспетчеризации: реализации требований имеют приоритет над методами расширений по умолчанию.

Часто задаваемые вопросы

Урок «Расширения протоколов и расширения типов» бесплатный?

Да — полный текст урока «Расширения протоколов и расширения типов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 3 уроков всего.

Чему я научусь в уроке «Расширения протоколов и расширения типов»?

Сравните расширения протоколов (добавляют реализации по умолчанию к протоколу, в том числе условно) с расширениями типов (добавляют API к одному конкретному типу). Разберитесь с поведением диспетчери… Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 3.

Сколько времени занимает урок «Расширения протоколов и расширения типов»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Основы протоколов и расширений
  2. Расширения протоколов и расширения типов
  3. Требования уровня типа и экземпляра
← Назад к Swift Academy