Hashable
Część sekcji Programowanie obiektowe ścieżki Swift w Coddy. Lekcja 40 z 57.
Hashable pozwala przechowywać wartości w Set lub używać ich jako kluczy w Dictionary. Hash to liczba obliczana na podstawie wartości, używana do jej szybkiego wyszukiwania. Struktury i wyliczenia, których wszystkie właściwości są typu Hashable, uzyskują tę zgodność, gdy ją zadeklarujesz:
struct Point: Hashable {
let x: Int, y: Int
}
var visited: Set<Point> = []
visited.insert(Point(x: 0, y: 0))
visited.insert(Point(x: 1, y: 0))
visited.insert(Point(x: 0, y: 0))
print(visited.count)
print(visited.contains(Point(x: 1, y: 0)))Wynik:
2
trueWartości, które można haszować, dobrze sprawdzają się jako klucze słownika, na przykład do zliczania wystąpień wartości strukturalnych:
struct Pair: Hashable {
let from: String, to: String
}
let trips = [Pair(from: "A", to: "B"), Pair(from: "B", to: "C"), Pair(from: "A", to: "B")]
var counts: [Pair: Int] = [:]
for t in trips { counts[t, default: 0] += 1 }
print(counts[Pair(from: "A", to: "B")]!)Wynik:
2Hashable opiera się na Equatable. Gdy == porównuje tylko niektóre właściwości, skrót musi używać tych samych właściwości, co odbywa się w hash(into:). W przeciwnym razie dwie równe wartości mogłyby otrzymać różne skróty, a zbiór przechowywałby obie:
struct User: Hashable {
let id: Int
var name: String
static func == (lhs: User, rhs: User) -> Bool { lhs.id == rhs.id }
func hash(into hasher: inout Hasher) { hasher.combine(id) }
}
let users: Set<User> = [User(id: 1, name: "Ada"), User(id: 1, name: "Ada L."), User(id: 2, name: "Bo")]
print(users.count)Wynik:
2Zasada do zapamiętania: równe wartości muszą mieć równe skróty. Wartości skrótów zmieniają się między uruchomieniami programu, więc nigdy ich nie zapisuj ani nie wyświetlaj; używaj ich wyłącznie za pośrednictwem zbiorów i słowników.
// równe wartości -> równe hashe (wymagane)
// różne wartości -> zwykle różne hashe
func hash(into hasher: inout Hasher) {
hasher.combine(id) // dokładnie te właściwości, które porównuje ==
}Wyzwanie
ŁatwyRobot porusza się po siatce o U, D, L, R — za każdym razem o jedno pole, zaczynając od (0, 0). Zaimplementuj Position (x, y) jako Hashable i dokończ explore(_:), która zwraca trzy wiersze: visited 5 cells (liczbę różnych pozycji, wliczając pozycję początkową), revisits 2 (ruchy, które zakończyły się na już odwiedzonym polu) oraz most visited (0, 0) x3 (pole, na które robot wszedł najwięcej razy, licząc pozycję początkową jako jedną wizytę; w przypadku remisu wygrywa pierwsze pole, które osiągnęło tę liczbę).
Dostarczony kod odczytuje jeden wiersz z ruchami i wyświetla każdy zwrócony wiersz.
Twój kod umieść w plikach Position.swift i Functions.swift. main.swift zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
// Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in explore(input[0]) { print(line) }
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasMetody i selfInicjalizatoryKlasy są referencjamiPowtórzenie — karta biblioteczna4Hermetyzacja
Kontrola dostępuTylko do odczytu z zewnątrzOchrona stanuInicjalizatory, które mogą zawieśćPodsumowanie — konto bankowe7Polimorfizm i typy generyczne
PolimorfizmRzutowanie typówFunkcje generyczneTypy generycznePodsumowanie – kalkulator kształtów2Struktury i typy wartościowe
StrukturySemantyka wartościMetody modyfikująceStruktura czy klasaPodsumowanie – element inwentarza5Dziedziczenie
PodklasyPrzesłanianie metodInicjalizatory i superfinal i hierarchiePodsumowanie — hierarchia pracowników8Standardowe protokoły
CustomStringConvertibleEquatableComparableHashablePodsumowanie — własne sortowanie11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Edytor online Swift