Протоколы как контракты
Определяйте контракты поведения независимо от типов.
«Протоколы как контракты» — бесплатный урок Swift Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Что такое протокол
Протокол определяет набор методов, свойств и других требований, которые должен реализовать соответствующий тип. Это контракт: любой тип, принимающий протокол, обязуется предоставить всё, что в нём объявлено.
protocol Greetable {
var name: String { get }
func greet() -> String
}Соответствие протоколу
Тип соответствует протоколу, принимая его и предоставляя каждое требование. Здесь структура реализует и свойство name, и метод greet().
protocol Greetable {
var name: String { get }
func greet() -> String
}
struct Person: Greetable {
let name: String
func greet() -> String { "Hello, I am " + name }
}
let p = Person(name: "Ada")
print(p.greet())Требования к свойствам
Протоколы указывают, должно ли свойство быть доступно для чтения ({ get }) или для чтения и записи ({ get set }). Сохранённое или вычисляемое свойство может удовлетворить требованию только для чтения.
protocol Identifiable {
var id: String { get }
}
struct User: Identifiable {
let id: String
}
print(User(id: "u-1").id)Требования к методам
Требования к методам перечисляют имя, параметры и возвращаемый тип, но не содержат тела. Соответствующие типы предоставляют реализацию.
protocol Shape {
func area() -> Double
}
struct Square: Shape {
let side: Double
func area() -> Double { side * side }
}
print(Square(side: 3).area())Требования к изменяющим методам
Для типов-значений методы, изменяющие self, должны быть отмечены как mutating. Объявляйте требование с помощью mutating, чтобы структуры могли ему соответствовать.
protocol Toggleable {
mutating func toggle()
}
struct Switch: Toggleable {
var isOn = false
mutating func toggle() { isOn.toggle() }
}
var s = Switch()
s.toggle()
print(s.isOn)Протоколы как типы
Протокол является полноценным типом. Его можно использовать для переменных, параметров и возвращаемых значений, принимая любое соответствующее ему значение.
protocol Animal { func sound() -> String }
struct Dog: Animal { func sound() -> String { "Woof" } }
struct Cat: Animal { func sound() -> String { "Meow" } }
let animals: [Animal] = [Dog(), Cat()]
for a in animals { print(a.sound()) }Полиморфизм через протоколы
Вызов метода протокола передаёт управление конкретному типу, который скрывается за значением. Это позволяет писать код, работающий с множеством типов через единый контракт.
protocol Describable { func describe() -> String }
struct Book: Describable { let t: String; func describe() -> String { "Book: " + t } }
struct Film: Describable { let t: String; func describe() -> String { "Film: " + t } }
func show(_ d: Describable) { print(d.describe()) }
show(Book(t: "Swift"))
show(Film(t: "Inception"))Требования к инициализаторам
Протоколы могут требовать инициализаторы. Классы должны отмечать реализацию как required, чтобы подклассы также её предоставляли.
protocol FromInt {
init(value: Int)
}
struct Wrapper: FromInt {
let value: Int
init(value: Int) { self.value = value }
}
print(Wrapper(value: 42).value)Наследование протоколов
Протокол может наследовать один или несколько других протоколов, добавляя дополнительные требования к унаследованным.
protocol Named { var name: String { get } }
protocol Aged: Named { var age: Int { get } }
struct Member: Aged {
let name: String
let age: Int
}
let m = Member(name: "Lin", age: 30)
print(m.name, m.age)Протоколы только для классов
Пометьте протокол с помощью AnyObject, чтобы ограничить соответствие классами. Это полезно для требований со ссылочной семантикой, например для делегирования.
protocol Counter: AnyObject {
var count: Int { get set }
}
class Box: Counter {
var count = 0
}
let b = Box()
b.count = 5
print(b.count)Проверка соответствия
Используйте is и as?, чтобы во время выполнения проверить, соответствует ли значение протоколу.
protocol Flyer { func fly() }
struct Bird: Flyer { func fly() { print("flap") } }
struct Rock {}
let things: [Any] = [Bird(), Rock()]
for t in things {
if let f = t as? Flyer { f.fly() } else { print("grounded") }
}Быстрая проверка
Проверьте своё понимание требований протоколов.
Итоги
Вы узнали, что протокол — это контракт: он объявляет требования к свойствам, методам, изменяющим методам и инициализаторам без реализаций. Типы соответствуют протоколу, выполняя каждое требование; протоколы можно использовать как типы для полиморфизма, они могут наследовать другие протоколы, а также ограничиваться классами с помощью AnyObject.
Часто задаваемые вопросы
Урок «Протоколы как контракты» бесплатный?
Да — полный текст урока «Протоколы как контракты» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Протоколы как контракты»?
Определяйте контракты поведения независимо от типов. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Протоколы как контракты»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Протоколы как контракты
- Реализации по умолчанию в расширениях
- Композиция протоколов
- Условное соответствие протоколу