0Pricing
Swift Academy · Lekcja

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

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