Swift Academy · Lektion

Betinget conformance

Lad generiske typer kun conformere, når begrænsningerne er opfyldt.

Lektion 4 af 413 trin

Betinget conformance er en gratis Swift Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Swift Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Swift Academy-kurset indeholder 4 lektioner i alt.

Hvad er betinget protokoloverensstemmelse?

Betinget protokoloverensstemmelse får en generisk type til at overholde en protokol, men kun når dens typeparametre opfylder bestemte begrænsninger. Det klassiske eksempel er, at et Array kun er Equatable, hvis dets Element er Equatable.

extension Array where Element: Equatable {
    func allEqual(to x: Element) -> Bool {
        allSatisfy { $0 == x }
    }
}

Indbygget eksempel

Standardbiblioteket bruger allerede dette: [Int] er Equatable, fordi Int er det. To arrayer sammenlignes som ens element for element.

let a = [1, 2, 3]
let b = [1, 2, 3]
print(a == b)

Erklæring af betinget protokoloverensstemmelse

Skriv en udvidelse, der tilføjer protokoloverensstemmelse med en where-klausul. Her overholder en indpakning Equatable kun, når dens værditype gør det.

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))

Hvorfor begrænsningen er vigtig

Uden begrænsningen kunne compileren ikke syntetisere ==, fordi sammenligning af den indpakkede værdi kræver, at selve værdien kan sammenlignes. where-klausulen giver netop denne garanti.

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))

Betinget Codable

Du kan også opnå betinget overensstemmelse med Codable. En beholder kan kodes, men kun når dens element kan det.

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)!)

Flere begrænsninger

En where-klausul kan angive flere krav, der er adskilt af kommaer.

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()!)

Betinget CustomStringConvertible

Gør kun en type udskrivbar, når dens indhold er det, og sammensæt beskrivelser ud fra elementerne.

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))

Indlejret betinget protokoloverensstemmelse

Betinget protokoloverensstemmelse kan sammensættes: et array med arrayer af Int er Equatable, fordi hvert lag viderefører begrænsningen.

let grid1 = [[1, 2], [3, 4]]
let grid2 = [[1, 2], [3, 4]]
print(grid1 == grid2)

Begrænsning til en anden protokol

where-klausulen kan kræve, at elementet overholder en protokol, du selv har defineret, så du får adgang til funktionalitet, der bygger på denne protokol.

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)

Begrænsninger af samme type

Du kan begrænse en associeret type til en bestemt type ved hjælp af ==. Her gælder metoderne kun for arrayer af String.

extension Array where Element == String {
    func joinedUpper() -> String {
        map { $0.uppercased() }.joined(separator: "-")
    }
}

print(["a", "b", "c"].joinedUpper())

Sådan bruger compileren det

Betinget protokoloverensstemmelse lader compileren give en protokols fordele præcis, når de er gyldige, så generisk kode både forbliver sikker og kan genbruges mest muligt.

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))

Hurtigt tjek

Test din forståelse af betinget protokoloverensstemmelse.

Opsamling

Betinget protokoloverensstemmelse bruger extension Type: Protocol where ... til kun at give overensstemmelse, når typeparametrene opfylder bestemte begrænsninger. Du har set det med Equatable, Codable og CustomStringConvertible, med protokolbegrænsninger, begrænsninger af samme type (==) og indlejring. Det holder generiske typer sikre og genanvendelige.

Gratis at komme i gang

Lær Swift med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
122
Lektioner
409

Ofte stillede spørgsmål

Er lektionen “Betinget conformance” gratis?

Ja — alle 3 lektioner i læringssporet Swift Academy, inklusive “Betinget conformance”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Swift Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Betinget conformance”?

Lad generiske typer kun conformere, når begrænsningerne er opfyldt. Du øver dig i Swift Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Swift Academy?

Der kræves ingen tidligere erfaring. Swift Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Betinget conformance”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Swift Academy-lektion?

Ja. Alle Swift Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Protokoller som kontrakter
  2. Standardimplementeringer i extensions
  3. Protokolkomposition
  4. Betinget conformance
← Tilbage til Swift Academy