Subíndices en Swift: Sintaxis y Aplicaciones Prácticas

Clase 14 de 27Curso de Programación Orientada a Objetos en Swift

Resumen

Aprende a dominar los subíndices en Swift con una explicación clara y ejemplos prácticos. Verás cómo esta sintaxis especial convierte tus tipos en APIs más expresivas, permitiéndote acceder a datos con corchetes, igual que en arrays y diccionarios, pero en tus propias clases, estructuras y enumerados.

¿Qué son los subíndices en Swift y cómo funcionan?

Los subíndices, en inglés subscripts, son un método especial que puedes definir dentro de una estructura, clase o enumerado para acceder a información usando corchetes. Ya los usas en arrays y diccionarios; la clave es que también puedes crearlos en tus propios tipos.

  • Se definen con la palabra clave subscript y parámetros de entrada.
  • Devuelven un valor de cualquier tipo compatible con tu diseño.
  • Pueden incluir getter y setter, como una propiedad computada (computed property).
  • Funcionan en clases, estructuras y enumerados.

¿Qué problemas resuelven los subíndices?

  • Acceso conciso con corchetes a datos internos.
  • APIs más legibles y naturales.
  • Uniformidad con colecciones nativas como arrays y diccionarios.

¿Cómo se escribe la sintaxis básica con un ejemplo práctico?

Un ejemplo directo: una estructura que genera la tabla de multiplicar de un número con un subíndice que toma un entero y devuelve el producto. Es la forma mínima para tener un subíndice funcional.

struct TimesTable {
    let multiplier: Int
    subscript(index: Int) -> Int {
        return multiplier * index
    }
}

¿Cómo se usa para la tabla del tres?

let threeTimesTable = TimesTable(multiplier: 3)
print("6 x 3 =", threeTimesTable[6]) // 18
  • El subíndice recibe un índice entero y devuelve un entero.
  • El resultado es el producto multiplier × index.
  • Puedes iterar en un rango con un bucle for para imprimir la tabla.
for idx in 0...10 {
    print("\(idx) x 3 =", threeTimesTable[idx])
}
  • Si amplías el rango (por ejemplo, hasta 100), obtienes más resultados sin cambiar la lógica.

¿Dónde más se aplican: colecciones y enumerados?

Los subíndices ya están implementados en arrays, diccionarios y conjuntos. Por eso accedes con corchetes. En diccionarios, por ejemplo, la clave puede ser String y el valor será del tipo almacenado (Int, Double, String, etc.).

¿Cómo crear un subíndice estático en un enumerado Planet?

Puedes definir subíndices también en enumerados, incluso como estáticos para no depender de una instancia. Ejemplo con un enumerado de planetas con valores crudos enteros empezando en 1.

enum Planet: Int {
    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune

    static subscript(n: Int) -> Planet {
        return Planet(rawValue: n)! // force unwrapping consciente
    }
}

let mars = Planet[4] // Mars
  • Aquí se usa rawValue para convertir el número en un caso del enumerado.
  • El resultado de Planet(rawValue:) es optional; se fuerza con “!”.
  • Si el número no corresponde a un planeta válido, fallará en tiempo de ejecución.

¿Qué precauciones tomar con valores no válidos?

  • El rawValue puede devolver nil.
  • El force unwrapping con “!” hace que tu código “pete” si el valor no es válido.
  • Buen ejercicio: validar que n esté dentro del rango permitido antes de forzar el unwrap.

¿Te gustaría ver más patrones útiles con subíndices o tienes un caso concreto en mente? Cuéntalo en los comentarios y seguimos la conversación.