Warunkowa zgodność
Warunkowe zapewnianie zgodności typów generycznych po spełnieniu ograniczeń.
Warunkowa zgodność to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 4 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.
Czym jest warunkowa zgodność?
Warunkowa zgodność sprawia, że typ generyczny jest zgodny z protokołem tylko wtedy, gdy jego parametry typu spełniają określone ograniczenia. Klasyczny przykład: Array jest zgodny z Equatable tylko wtedy, gdy jego typ Element jest zgodny z Equatable.
extension Array where Element: Equatable {
func allEqual(to x: Element) -> Bool {
allSatisfy { $0 == x }
}
}Przykład z biblioteki standardowej
Biblioteka standardowa już to wykorzystuje: [Int] jest zgodny z Equatable, ponieważ Int jest z nim zgodny. Dwie tablice są porównywane element po elemencie.
let a = [1, 2, 3]
let b = [1, 2, 3]
print(a == b)Deklarowanie warunkowej zgodności
Należy napisać rozszerzenie, które dodaje zgodność z protokołem za pomocą klauzuli where. W tym przykładzie opakowujący typ jest zgodny z Equatable tylko wtedy, gdy jego typ wartości również jest z nim zgodny.
struct Pair<T> {
let first: T
let second: T
}
extension Pair: Equatable where T: Equatable {
static func == (l: Pair, r: Pair) -> Bool {
l.first == r.first && l.second == r.second
}
}
print(Pair(first: 1, second: 2) == Pair(first: 1, second: 2))Dlaczego ograniczenie ma znaczenie
Bez tego ograniczenia kompilator nie mógłby automatycznie wygenerować ==, ponieważ porównanie opakowanej wartości wymaga, aby sama wartość była porównywalna. Klauzula where zapewnia dokładnie taką gwarancję.
struct Box<T> { let value: T }
extension Box: Equatable where T: Equatable {}
print(Box(value: "hi") == Box(value: "hi"))
print(Box(value: 5) == Box(value: 9))Warunkowa zgodność z Codable
Można warunkowo zapewnić zgodność z Codable. Kontener jest kodowalny tylko wtedy, gdy kodowalny jest jego element.
struct Wrapper<T> { let payload: T }
extension Wrapper: Codable where T: Codable {}
let w = Wrapper(payload: 42)
let data = try! JSONEncoder().encode(w)
print(String(data: data, encoding: .utf8)!)Wiele ograniczeń
Klauzula where może zawierać kilka wymagań oddzielonych przecinkami.
struct Stack<T> { var items: [T] = [] }
extension Stack where T: Comparable {
func maxItem() -> T? { items.max() }
}
var s = Stack<Int>()
s.items = [3, 9, 1]
print(s.maxItem()!)Warunkowa zgodność z CustomStringConvertible
Typ można przystosować do wyświetlania tylko wtedy, gdy można wyświetlać jego zawartość, składając opisy z poszczególnych elementów.
struct Labeled<T> { let label: String; let value: T }
extension Labeled: CustomStringConvertible where T: CustomStringConvertible {
var description: String { label + ": " + value.description }
}
print(Labeled(label: "Age", value: 30))Zagnieżdżona warunkowa zgodność
Warunkowa zgodność może być składana: tablica tablic elementów Int jest zgodna z Equatable, ponieważ każda warstwa przekazuje dalej to ograniczenie.
let grid1 = [[1, 2], [3, 4]]
let grid2 = [[1, 2], [3, 4]]
print(grid1 == grid2)Ograniczenie do innego protokołu
Klauzula where może wymagać, aby element był zgodny ze zdefiniowanym przez Państwa protokołem, udostępniając funkcjonalność opartą na tym protokole.
protocol Priced { var price: Double { get } }
struct Item: Priced { let price: Double }
extension Array where Element: Priced {
var totalPrice: Double { reduce(0) { $0 + $1.price } }
}
print([Item(price: 1.5), Item(price: 2.5)].totalPrice)Ograniczenia równości typów
Za pomocą == można ograniczyć typ skojarzony do konkretnego typu. W tym przykładzie metody dotyczą tylko tablic elementów String.
extension Array where Element == String {
func joinedUpper() -> String {
map { $0.uppercased() }.joined(separator: "-")
}
}
print(["a", "b", "c"].joinedUpper())Jak korzysta z tego kompilator
Warunkowa zgodność pozwala kompilatorowi udostępniać korzyści wynikające z protokołu dokładnie wtedy, gdy są one uzasadnione, dzięki czemu kod generyczny pozostaje bezpieczny i maksymalnie uniwersalny.
struct Optional2<T> { let value: T? }
extension Optional2: Equatable where T: Equatable {
static func == (l: Optional2, r: Optional2) -> Bool { l.value == r.value }
}
print(Optional2(value: 1) == Optional2(value: 1))Szybkie sprawdzenie
Sprawdź swoją wiedzę na temat warunkowej zgodności.
Podsumowanie
Warunkowa zgodność wykorzystuje konstrukcję extension Type: Protocol where ..., aby zapewnić zgodność tylko wtedy, gdy parametry typu spełniają określone ograniczenia. Zobaczyłeś jej zastosowanie z Equatable, Codable i CustomStringConvertible, a także ograniczenia dotyczące protokołów, ograniczenia równości typów (==) oraz zagnieżdżanie. Dzięki niej typy generyczne pozostają bezpieczne i uniwersalne.
Często zadawane pytania
Czy lekcja „Warunkowa zgodność” jest bezpłatna?
Tak — pełny tekst „Warunkowa zgodność” 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 „Warunkowa zgodność”?
Warunkowe zapewnianie zgodności typów generycznych po spełnieniu ograniczeń. Ć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 4 z 4.
Ile czasu zajmuje lekcja „Warunkowa zgodność”?
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ść