Semantica di uguaglianza personalizzata
Implementi regole di uguaglianza corrette per il dominio.
Semantica di uguaglianza personalizzata è una lezione Swift Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Swift Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Swift Academy include 4 lezioni in totale.
Quando == predefinito non è corretto
Il == sintetizzato confronta ogni proprietà memorizzata. A volte è troppo restrittivo (quando interessa solo un id) o troppo permissivo. In questi casi deve scrivere personalmente ==.
Uguaglianza basata sull'identità
Consideri due record uguali quando i loro id corrispondono, ignorando gli altri campi:
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)) // trueUguaglianza senza distinzione tra maiuscole e minuscole
Normalizzi i valori prima del confronto:
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")) // trueMantenere coerente Hashable
Se personalizza ==, DEVE aggiornare anche hash(into:) in modo che utilizzi gli stessi campi; altrimenti valori uguali potrebbero produrre hash diversi e danneggiare i Set.
Far corrispondere == e hash(into:)
Entrambi utilizzano solo id, mantenendo la coerenza:
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) // 1Uguaglianza che ignora una cache
Escluda dal confronto i campi derivati o memorizzati nella cache:
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) // trueUguaglianza tollerante tra numeri a virgola mobile
Confronti i double entro un epsilon invece di confrontarli esattamente:
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)) // trueUguaglianza su un sottoinsieme di campi
Confronti un sottoinsieme significativo per definire l'uguaglianza nel dominio:
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)) // trueRispettare le leggi di Equatable
Un == personalizzato deve rimanere riflessivo (a == a), simmetrico (a == b implica b == a) e transitivo. La violazione di queste proprietà confonde le collezioni e gli algoritmi.
Un'implementazione simmetrica
Confrontare le forme normalizzate mantiene intatta la simmetria:
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 trueUguaglianza personalizzata in un Set
Poiché l'uguaglianza e l'hashing basati solo sull'id sono coerenti, il Set considera i valori con lo stesso id come un unico elemento:
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) // 1Verifica rapida
Dopo aver scritto un == personalizzato che utilizza solo alcuni campi, cos'altro deve fare?
Riepilogo
Ha imparato a definire un'uguaglianza personalizzata:
- Scriva il proprio
==quando il confronto predefinito dell'intera struct non è corretto - Casi comuni: solo id, distinzione tra maiuscole e minuscole, numeri a virgola mobile con epsilon, esclusione delle cache
- Mantenga
hash(into:)coerente utilizzando gli stessi campi - Mantenga l'uguaglianza riflessiva, simmetrica e transitiva
Corso completato! Successivo: CustomStringConvertible e Mirror.
Domande Frequenti
La lezione «Semantica di uguaglianza personalizzata» è gratuita?
Sì — il testo completo di «Semantica di uguaglianza personalizzata» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Swift Academy, passa a CoddyKit PRO. Il corso Swift Academy include 4 lezioni in totale.
Cosa imparerò in «Semantica di uguaglianza personalizzata»?
Implementi regole di uguaglianza corrette per il dominio. Eserciti Swift Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Swift Academy?
Non è richiesta alcuna esperienza precedente. Swift Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Semantica di uguaglianza personalizzata»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Swift Academy?
Sì. Ogni lezione Swift Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Equatable sintetizzato
- Hashable e hash(into:)
- Comparable e ordinamento
- Semantica di uguaglianza personalizzata