Swift Academy · Lektion

Anpassad likhetssemantik

Implementera likhetsregler som stämmer med domänen.

Lektion 4 av 413 steg

Anpassad likhetssemantik är en gratis lektion i Swift Academy på CoddyKit. Detta är lektion 4 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Swift Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Swift Academy innehåller totalt 4 lektioner.

När standardoperatorn == är fel

Syntetiserad == jämför alla lagrade egenskaper. Ibland är det för strikt (Ni bryr Er bara om ett id) eller för löst. Då skriver Ni == själva.

Identitetsbaserad likhet

Behandla två poster som lika när deras id:n matchar, och ignorera övriga fält:

struct Account: Equatable {
    let id: Int
    var balance: Int
    static func == (l: Account, r: Account) -> Bool { l.id == r.id }
}
print(Account(id: 1, balance: 10) == Account(id: 1, balance: 999))  // true

Skiftlägesokänslig likhet

Normalisera innan Ni jämför:

struct Username: Equatable {
    let raw: String
    static func == (l: Username, r: Username) -> Bool {
        l.raw.lowercased() == r.raw.lowercased()
    }
}
print(Username(raw: "Ann") == Username(raw: "ANN"))  // true

Håll Hashable konsekvent

Om Ni anpassar == MÅSTE Ni uppdatera hash(into:) så att samma fält används. Annars kan lika värden få olika hashvärden och förstöra Set-strukturer.

Matchande == och hash(into:)

Båda använder endast id och förblir därmed konsekventa:

struct User: Hashable {
    let id: Int
    var name: String
    static func == (l: User, r: User) -> Bool { l.id == r.id }
    func hash(into h: inout Hasher) { h.combine(id) }
}
print(Set([User(id: 1, name: "A"), User(id: 1, name: "B")]).count)  // 1

Likhet som ignorerar en cache

Uteslut härledda eller cachade fält från jämförelsen:

struct Doc: Equatable {
    let text: String
    var cachedWordCount: Int
    static func == (l: Doc, r: Doc) -> Bool { l.text == r.text }
}
let a = Doc(text: "hi", cachedWordCount: 1)
let b = Doc(text: "hi", cachedWordCount: 999)
print(a == b)  // true

Tolerant likhet för flyttal

Jämför double-värden inom ett epsilon i stället för exakt:

struct Measure: Equatable {
    let value: Double
    static func == (l: Measure, r: Measure) -> Bool {
        abs(l.value - r.value) < 0.0001
    }
}
print(Measure(value: 0.1 + 0.2) == Measure(value: 0.3))  // true

Likhet baserad på en delmängd av fält

Jämför en meningsfull delmängd för domänspecifik likhet:

struct Card: Equatable {
    let rank: Int
    let suit: String
    let isFaceUp: Bool   // display state, not identity
    static func == (l: Card, r: Card) -> Bool {
        l.rank == r.rank && l.suit == r.suit
    }
}
print(Card(rank: 1, suit: "H", isFaceUp: true) == Card(rank: 1, suit: "H", isFaceUp: false))  // true

Följ Equatable-lagarna

En anpassad == måste vara reflexiv (a == a), symmetrisk (a == b innebär b == a) och transitiv. Om dessa regler bryts blir samlingar och algoritmer förvirrade.

En symmetrisk implementation

Genom att jämföra normaliserade former bevaras symmetrin:

struct Email: Equatable {
    let address: String
    static func == (l: Email, r: Email) -> Bool {
        l.address.lowercased() == r.address.lowercased()
    }
}
let x = Email(address: "A@x.com")
let y = Email(address: "a@X.com")
print(x == y, y == x)  // true true

Anpassad likhet i en Set

Eftersom likhet och hashning som endast använder id överensstämmer behandlar Set samma id-värden som ett enda värde:

struct Item: Hashable {
    let id: Int
    var note: String
    static func == (l: Item, r: Item) -> Bool { l.id == r.id }
    func hash(into h: inout Hasher) { h.combine(id) }
}
let s: Set<Item> = [Item(id: 1, note: "x"), Item(id: 1, note: "y")]
print(s.count)  // 1

Snabb kontroll

Vad måste Ni också göra efter att ha skrivit en anpassad == som endast använder vissa fält?

Sammanfattning

Ni har lärt Er om anpassad likhet:

  • Skriv en egen == när standardjämförelsen av hela structen är fel
  • Vanliga fall: endast id, skiftlägesokänslighet, epsilon för flyttal och att ignorera cacher
  • Håll hash(into:) konsekvent genom att använda samma fält
  • Förbli reflexiv, symmetrisk och transitiv

Kursen är klar! Nästa: CustomStringConvertible och Mirror.

Gratis att börja

Lär dig Swift med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
122
Lektioner
409

Vanliga frågor

Är lektionen ”Anpassad likhetssemantik” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Swift Academy, inklusive ”Anpassad likhetssemantik”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Swift Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Anpassad likhetssemantik”?

Implementera likhetsregler som stämmer med domänen. Ni övar på Swift Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Swift Academy?

Du behöver inga förkunskaper. Utbildningen i Swift Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.

Hur lång tid tar lektionen ”Anpassad likhetssemantik”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Swift Academy-lektionen?

Ja. Varje Swift Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Syntetiserad Equatable
  2. Hashable och hash(into:)
  3. Comparable och sortering
  4. Anpassad likhetssemantik
← Tillbaka till Swift Academy