Sobes.tech
Junior

Co należy zrobić, aby struktura lub klasa użytkownika stała się kluczem w słowniku?

sobes.tech AI

Odpowiedź od AI

Struktury lub klasy muszą być haszowalne. Dla struktury lub klasy zawierającej tylko typy haszowalne (np. Int, String, Bool), kompilator automatycznie generuje implementację protokołu Hashable. Jeśli struktura lub klasa zawiera typy niehaszowalne lub wymaga specjalnej logiki haszowania, konieczne jest:

  1. Implementacja protokołu Hashable.
  2. W metodzie hash(into:) dodanie komponentów haszowalnych instancji do dostarczonego hashera.
struct User: Hashable {
    let id: UUID // UUID jest domyślnie Hashable
    let name: String // String jest domyślnie Hashable

    // Automatycznie generowane, jeśli wszystkie właściwości są Hashable
    // func hash(into hasher: inout Hasher) {
    //     hasher.combine(id)
    //     hasher.combine(name)
    // }
}

class Settings: Hashable {
    var difficulty: Int
    var volume: Float

    init(difficulty: Int, volume: Float) {
        self.difficulty = difficulty
        self.volume = volume
    }

    // Ręczna implementacja dla klasy
    func hash(into hasher: inout Hasher) {
        hasher.combine(difficulty)
        hasher.combine(volume)
    }

    // Również wymagana jest implementacja `Equatable`
    static func == (lhs: Settings, rhs: Settings) -> Bool {
        lhs.difficulty == rhs.difficulty && lhs.volume == rhs.volume
    }
}

// Przykład użycia
let users: [User: String] = [User(id: UUID(), name: "Alice"): "Manager"]
let gameSettings: [Settings: Bool] = [Settings(difficulty: 5, volume: 0.8): true]

Wymagana jest również implementacja protokołu Equatable, ponieważ Hashable dziedziczy po Equatable. Kompilator automatycznie generuje implementację Equatable dla struktur, których właściwości są również Equatable. Dla klas lub struktur z właściwościami nie-Equatable (lub dla niestandardowej logiki porównania) konieczna jest ręczna implementacja ==.