0Pricing
Swift Academy · Lekcja

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

Ró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"))  // true

Zachowanie 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)  // 1

Ró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)  // true

Tolerancyjna 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))  // true

Ró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))  // true

Przestrzeganie 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 true

Niestandardowa 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)  // 1

Szybkie 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

  1. Syntezowane Equatable
  2. Hashable i hash(into:)
  3. Comparable i sortowanie
  4. Niestandardowa semantyka równości
← Powrót do Swift Academy