0Pricing
Swift Academy · Lección

Hashable y hash(into:)

Permita utilizar valores como claves de diccionario y miembros de conjuntos.

Hashable y hash(into:) es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 4 lecciones en total.

¿Qué es Hashable?

Hashable se basa en Equatable y proporciona un valor hash. Es necesario para utilizar un tipo como elemento de un Set o como clave de un Dictionary.

Hashable automático

Al igual que con Equatable, las estructuras y enumeraciones cuyos miembros son Hashable lo obtienen sintetizado:

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

Uso de un tipo como clave de un Dictionary

Los tipos Hashable pueden utilizarse como claves de un diccionario:

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"

El contrato de Hashable

Dos valores que son iguales (==) DEBEN producir el mismo hash. Si personaliza uno de los dos, manténgalos coherentes; de lo contrario, los sets y diccionarios no funcionarán correctamente.

hash(into:) personalizado

Implemente hash(into:) incorporando las propiedades relevantes al hasher:

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

Combinación de varios campos

Incorpore todos los campos que participan en la igualdad:

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

Por qué solo se deben usar los campos de identidad

Calcule el hash únicamente de los campos utilizados en ==. Incluir campos adicionales y mutables puede romper la regla de que valores iguales implican el mismo hash:

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

Enumeraciones Hashable

Las enumeraciones son Hashable automáticamente (incluidos sus valores asociados cuando estos son Hashable):

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

Eliminar duplicados con un Set

Un uso común consiste en eliminar duplicados pasando los valores por un Set:

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

Hasher se aleatoriza en cada ejecución

Los valores hash se inicializan con una semilla distinta en cada ejecución del programa, por lo que nunca debe guardar un hashValue en disco ni depender de su número exacto entre ejecuciones:

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

Contar con un Dictionary

Las claves Hashable permiten contar frecuencias; es un patrón muy común:

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

Comprobación rápida

¿Qué regla debe respetar hash(into:) con respecto a ==?

Resumen

Ha aprendido Hashable:

  • Hashable refina Equatable y es necesario para las claves de Set/Dictionary
  • Se sintetiza para estructuras y enumeraciones cuyos miembros son Hashable
  • En hash(into:) personalizado, combine únicamente los campos de identidad utilizados en ==
  • Los valores iguales deben producir el mismo hash; los hashes se aleatorizan en cada ejecución

Siguiente: Comparable y la ordenación.

Preguntas frecuentes

¿La lección «Hashable y hash(into:)» es gratis?

Sí — el texto completo de «Hashable y hash(into:)» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Hashable y hash(into:)»?

Permita utilizar valores como claves de diccionario y miembros de conjuntos. Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Swift Academy?

No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «Hashable y hash(into:)»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Swift Academy?

Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Equatable sintetizado
  2. Hashable y hash(into:)
  3. Comparable y ordenación
  4. Semántica de igualdad personalizada
← Volver a Swift Academy