Niestandardowa semantyka równości
Implementowanie reguł równości właściwych dla domeny.
Niestandardowa semantyka równości 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.
Kiedy domyślne == jest niewłaściwe
Automatycznie wygenerowany operator == porównuje każdą przechowywaną właściwość. Czasami jest to zbyt restrykcyjne (liczy się tylko identyfikator) albo zbyt pobłażliwe. Wtedy należy samodzielnie napisać ==.
Równość oparta na tożsamości
Dwa rekordy należy uznać za równe, gdy mają takie same identyfikatory, ignorując pozostałe pola:
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)) // trueRówność bez uwzględniania wielkości liter
Przed porównaniem należy znormalizować wartości:
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")) // trueZachowanie spójności z Hashable
Jeśli dostosują Państwo ==, MUSZĄ również zaktualizować hash(into:), aby używała tych samych pól; w przeciwnym razie równe wartości mogą otrzymać różne skróty i uszkodzić działanie zbiorów Set.
Zgodne == i hash(into:)
Oba elementy używają wyłącznie id, zachowując spójność:
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) // 1Równość ignorująca pamięć podręczną
Pola pochodne lub buforowane należy wykluczyć z porównania:
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) // trueTolerancyjna równość liczb zmiennoprzecinkowych
Liczby typu double należy porównywać z dokładnością do epsilonu zamiast porównywać je dokładnie:
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)) // trueRówność na podstawie podzbioru pól
W przypadku równości dziedzinowej należy porównywać istotny podzbiór pól:
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)) // truePrzestrzeganie praw Equatable
Niestandardowy operator == musi zachowywać zwrotność (a == a), symetrię (z a == b wynika b == a) oraz przechodniość. Naruszenie tych zasad wprowadza zamieszanie w kolekcjach i algorytmach.
Implementacja zachowująca symetrię
Porównywanie znormalizowanych postaci pozwala zachować symetrię:
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 trueNiestandardowa równość w zbiorze Set
Ponieważ równość i haszowanie oparte wyłącznie na id są zgodne, Set traktuje wartości o tym samym id jako jedną wartość:
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) // 1Szybkie sprawdzenie
Co jeszcze trzeba zrobić po napisaniu niestandardowego == używającego tylko niektórych pól?
Podsumowanie
Poznali Państwo niestandardową równość:
- Należy samodzielnie napisać
==, gdy domyślne porównywanie całej struktury jest niewłaściwe - Częste przypadki: porównywanie tylko identyfikatora, ignorowanie wielkości liter, liczby zmiennoprzecinkowe z tolerancją epsilonu, ignorowanie pamięci podręcznych
- Należy zachować spójność
hash(into:), używając tych samych pól - Należy zachować zwrotność, symetrię i przechodniość
Kurs ukończony! Następnie: CustomStringConvertible i Mirror.
Często zadawane pytania
Czy lekcja „Niestandardowa semantyka równości” jest bezpłatna?
Tak — pełny tekst „Niestandardowa semantyka równości” 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 „Niestandardowa semantyka równości”?
Implementowanie reguł równości właściwych dla domeny. Ć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 „Niestandardowa semantyka równości”?
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
- Syntezowane Equatable
- Hashable i hash(into:)
- Comparable i sortowanie
- Niestandardowa semantyka równości