0Pricing
Swift Academy · Lekcja

Hashable i hash(into:)

Umożliwianie używania typów jako kluczy słowników i elementów zbiorów.

Hashable i hash(into:) to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 2 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.

Czym jest Hashable

Hashable opiera się na Equatable i udostępnia wartość skrótu. Jest wymagany, aby użyć typu jako elementu Set lub klucza Dictionary.

Automatyczne zapewnianie zgodności z Hashable

Podobnie jak w przypadku Equatable, struktury i typy wyliczeniowe zawierające elementy zgodne z Hashable otrzymują tę zgodność automatycznie:

struct Point: Hashable {
    let x: Int
    let y: Int
}
let set: Set<Point> = [Point(x: 0, y: 0), Point(x: 0, y: 0)]
print(set.count)  // 1  -- duplicate collapsed

Używanie typu jako klucza słownika

Typy zgodne z Hashable mogą służyć jako klucze słownika:

struct Coord: Hashable { let r: Int; let c: Int }
var grid: [Coord: String] = [:]
grid[Coord(r: 0, c: 0)] = "start"
print(grid[Coord(r: 0, c: 0)]!)  // "start"

Zasady Hashable

Dwie równe wartości (==) MUSZĄ generować ten sam skrót. Jeśli dostosują Państwo jeden z tych elementów, należy zachować spójność obu, w przeciwnym razie zbiory i słowniki nie będą działać poprawnie.

Niestandardowa metoda hash(into:)

Metodę hash(into:) należy zaimplementować, przekazując odpowiednie właściwości do obiektu haszującego:

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

Łączenie wielu pól

Należy przekazać każde pole uczestniczące w ustalaniu równości:

struct Pair: Hashable {
    let a: Int
    let b: String
    func hash(into hasher: inout Hasher) {
        hasher.combine(a)
        hasher.combine(b)
    }
}
print(Pair(a: 1, b: "x").hashValue == Pair(a: 1, b: "x").hashValue)  // true

Dlaczego należy używać tylko pól tożsamości

Należy haszować tylko pola używane w ==. Dołączenie dodatkowych, zmiennych pól może naruszyć zasadę, że równe wartości muszą mieć ten sam skrót:

struct Doc: Hashable {
    let id: Int       // identity
    var title: String // not part of equality
    func hash(into hasher: inout Hasher) { hasher.combine(id) }
    static func == (l: Doc, r: Doc) -> Bool { l.id == r.id }
}
print(Doc(id: 1, title: "v1") == Doc(id: 1, title: "v2"))  // true

Typy wyliczeniowe Hashable

Typy wyliczeniowe automatycznie są zgodne z Hashable (również z wartościami skojarzonymi, jeśli te wartości są zgodne z Hashable):

enum Direction: Hashable { case north, south, east, west }
let visited: Set<Direction> = [.north, .north, .east]
print(visited.count)  // 2

Usuwanie duplikatów za pomocą Set

Częste zastosowanie: usuwanie duplikatów przez przejście przez Set:

let nums = [1, 2, 2, 3, 3, 3]
let unique = Array(Set(nums)).sorted()
print(unique)  // [1, 2, 3]

Hasher jest losowany dla każdego uruchomienia

Wartości skrótów są inicjalizowane osobno dla każdego uruchomienia programu, dlatego nigdy nie należy zapisywać hashValue na dysku ani polegać na jego dokładnej wartości między kolejnymi uruchomieniami:

struct K: Hashable { let v: Int }
let h1 = K(v: 5).hashValue
// h1 is stable within this run only
print(K(v: 5) == K(v: 5))  // true  -- equality is what to rely on

Zliczanie za pomocą słownika

Klucze zgodne z Hashable umożliwiają zliczanie częstotliwości — to bardzo częsty schemat:

let letters = ["a", "b", "a", "c", "b", "a"]
var counts: [String: Int] = [:]
for l in letters { counts[l, default: 0] += 1 }
print(counts["a"]!)  // 3

Szybkie sprawdzenie

Jaką zasadę musi spełniać hash(into:) względem ==?

Podsumowanie

Poznali Państwo Hashable:

  • Hashable rozszerza Equatable i jest wymagany w przypadku elementów Set oraz kluczy Dictionary
  • Zgodność jest generowana automatycznie dla struktur i typów wyliczeniowych zawierających elementy zgodne z Hashable
  • Niestandardowa metoda hash(into:) — należy łączyć tylko pola tożsamości używane w ==
  • Równe wartości muszą mieć takie same skróty, a skróty są losowane osobno dla każdego uruchomienia

Następnie: Comparable i sortowanie.

Często zadawane pytania

Czy lekcja „Hashable i hash(into:)” jest bezpłatna?

Tak — pełny tekst „Hashable i hash(into:)” 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 „Hashable i hash(into:)”?

Umożliwianie używania typów jako kluczy słowników i elementów zbiorów. Ć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 2 z 4.

Ile czasu zajmuje lekcja „Hashable i hash(into:)”?

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