Kompozycja protokołów
Łączenie wymagań wielu protokołów za pomocą &.
Kompozycja protokołów to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.
Łączenie protokołów
Czasami wartość musi jednocześnie spełniać wymagania kilku protokołów. Swift pozwala łączyć protokoły za pomocą operatora &: SomeProtocol & AnotherProtocol.
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }Parametr złożony
Parametr typu Named & Aged akceptuje dowolną wartość zgodną z oboma protokołami.
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }
struct Person: Named, Aged {
let name: String
let age: Int
}
func intro(_ x: Named & Aged) {
print(x.name + " is " + String(x.age))
}
intro(Person(name: "Sam", age: 28))Dlaczego nie dziedziczenie?
Kompozycja pozwala wymagać obu protokołów w miejscu wywołania bez tworzenia nowego połączonego protokołu. Dzięki temu protokoły pozostają niewielkie i wielokrotnego użytku.
protocol Drawable { func draw() -> String }
protocol Resizable { func resize(_ f: Double) -> String }
struct Icon: Drawable, Resizable {
func draw() -> String { "drawing" }
func resize(_ f: Double) -> String { "x" + String(f) }
}
func render(_ v: Drawable & Resizable) {
print(v.draw(), v.resize(2))
}
render(Icon())Trzy protokoły lub więcej
Możecie łączyć tyle protokołów, ile potrzeba, dodając kolejne operatory &.
protocol A { func a() -> String }
protocol B { func b() -> String }
protocol C { func c() -> String }
struct X: A, B, C {
func a() -> String { "a" }
func b() -> String { "b" }
func c() -> String { "c" }
}
func use(_ v: A & B & C) { print(v.a(), v.b(), v.c()) }
use(X())Kompozycja z klasą
Możecie połączyć typ klasy z protokołami: SomeClass & SomeProtocol wymaga, aby wartość była instancją tej klasy lub jej podklasy ORAZ była zgodna z protokołem.
class Vehicle { var speed = 0 }
protocol Electric { var battery: Int { get } }
class Tesla: Vehicle, Electric { var battery = 100 }
func check(_ v: Vehicle & Electric) {
print(v.speed, v.battery)
}
check(Tesla())Zwracanie kompozycji
Funkcja może zwracać typ złożony, obiecując wywołującemu, że wynik będzie zgodny ze wszystkimi wymienionymi protokołami.
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }
struct Person: Named, Aged { let name: String; let age: Int }
func makePerson() -> Named & Aged {
Person(name: "Eve", age: 22)
}
let p = makePerson()
print(p.name, p.age)typealias dla kompozycji
Nadajcie kompozycji czytelną nazwę za pomocą typealias, aby móc jej używać ponownie bez powtarzania łańcucha operatorów &.
protocol Codable2 { func encode() -> String }
protocol Loggable { func log() -> String }
typealias Persistable = Codable2 & Loggable
struct Record: Persistable {
func encode() -> String { "data" }
func log() -> String { "logged" }
}
func save(_ r: Persistable) { print(r.encode(), r.log()) }
save(Record())Kompozycja w kolekcjach
Możecie przechowywać wartości typu złożonego w tablicach i uzyskiwać dostęp do elementów wszystkich protokołów dla każdego elementu.
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }
struct P: Named, Aged { let name: String; let age: Int }
let group: [Named & Aged] = [P(name: "A", age: 1), P(name: "B", age: 2)]
for g in group { print(g.name, g.age) }Kompozycja ze standardowymi protokołami
Kompozycja jest szczególnie przydatna w przypadku protokołów bibliotecznych. Możecie na przykład wymagać jednocześnie CustomStringConvertible i Equatable.
func report<T>(_ items: [T]) where T: CustomStringConvertible & Equatable {
for i in items { print(i.description) }
}
report([1, 2, 3])Puste protokoły jako znaczniki
Kompozycja może łączyć protokół znacznikowy (bez wymagań) z protokołem określającym funkcjonalność, aby wyrazić intencję w systemie typów.
protocol Secure {}
protocol Sendable2 { func send() -> String }
struct Packet: Secure, Sendable2 {
func send() -> String { "sent securely" }
}
func transmit(_ p: Secure & Sendable2) { print(p.send()) }
transmit(Packet())Kompozycja a typy generyczne
Kompozycja (A & B) usuwa informację o konkretnym typie, natomiast typy generyczne (<T: A & B>) ją zachowują. Typów generycznych należy używać, gdy trzeba powiązać typy parametrów i wartości zwracanych.
protocol A { func a() -> String }
protocol B { func b() -> String }
struct S: A, B { func a() -> String { "a" }; func b() -> String { "b" } }
func generic<T: A & B>(_ x: T) -> T { print(x.a(), x.b()); return x }
_ = generic(S())Szybkie sprawdzenie
Sprawdź swoją wiedzę na temat kompozycji protokołów.
Podsumowanie
Kompozycja protokołów za pomocą & pozwala wymagać jednoczesnej zgodności z wieloma protokołami (i opcjonalnie jedną klasą), bez definiowania nowego połączonego protokołu. Kompozycjom można nadawać nazwy za pomocą typealias i używać ich w parametrach, wartościach zwracanych oraz kolekcjach. Zobaczyłeś także, czym kompozycja różni się od typów generycznych pod względem zachowywania konkretnych typów.
Często zadawane pytania
Czy lekcja „Kompozycja protokołów” jest bezpłatna?
Tak — pełny tekst „Kompozycja protokołów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Kompozycja protokołów”?
Łączenie wymagań wielu protokołów za pomocą &. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Swift Academy?
Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Kompozycja protokołów”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?
Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Protokoły jako kontrakty
- Implementacje domyślne w rozszerzeniach
- Kompozycja protokołów
- Warunkowa zgodność