0Pricing
Swift Academy · Lekcja

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

  1. Protokoły jako kontrakty
  2. Implementacje domyślne w rozszerzeniach
  3. Kompozycja protokołów
  4. Warunkowa zgodność
← Powrót do Swift Academy