Anpassad likhetssemantik
Implementera likhetsregler som stämmer med domänen.
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)) // trueSkiftlä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")) // trueHå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) // 1Likhet 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) // trueTolerant 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)) // trueLikhet 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)) // trueFö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 trueAnpassad 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) // 1Snabb 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.
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
- Syntetiserad Equatable
- Hashable och hash(into:)
- Comparable och sortering
- Anpassad likhetssemantik