Introducción: El "truco" que espera a cada desarrollador de Swift
\n\nImagina la situación: escribes código en Swift con confianza, todo va bien, y de repente necesitas tomar los primeros tres caracteres de una cadena. Sin pensarlo, escribes algo como myString[0..<3] — y obtienes... un error de compilación. ¿Te suena familiar?
Bienvenido al mundo de String substring en Swift. Es uno de esos temas que causa un verdadero dolor a los principiantes e incluso a desarrolladores experimentados que vienen de otros lenguajes. La pregunta "How does String substring work in Swift" en Stack Overflow ha acumulado miles de visitas — y no es casualidad.
\n\nEn este artículo analizaremos por qué Swift es tan "extraño" al trabajar con subcadenas, cómo usar correctamente substring en Swift, y qué nuevas posibilidades han aparecido en las versiones recientes. ¡Allá vamos!
\n\n¿Por qué Swift no permite simplemente cortar un trozo de cadena?
\n\nEn la mayoría de los lenguajes (Python, JavaScript, C#) una cadena es simplemente un array de caracteres. ¿Quieres una subcadena? Escribe str[0:3] y obtén el resultado. En Swift es diferente.
La razón está en el trabajo con Unicode. Las cadenas en Swift no son solo bytes o caracteres ASCII. Están compuestas de clústeres de grafemas (grapheme clusters). Un solo carácter que ve el usuario (por ejemplo, "é" o "👍🏽") puede ocupar varios Character o incluso varios Unicode.Scalar. Imagina que cortas una cadena en medio de uno de esos clústeres — obtendrías datos corruptos.
Por eso Swift utiliza índices (String.Index), en lugar de números enteros. Esto garantiza que nunca dividirás un carácter por la mitad.
Fundamentos: String.Index y extracción simple de subcadenas
\n\nComencemos con un ejemplo básico. Supongamos que tenemos una cadena:
\n\nlet fullString = "¡Hola, Swift!"\n// Queremos tomar la palabra "Swift"\nlet startIndex = fullString.index(fullString.startIndex, offsetBy: 6)\nlet endIndex = fullString.index(fullString.startIndex, offsetBy: 11)\nlet substring = fullString[startIndex..<endIndex]\nprint(substring) // Imprime: "Swift"\n\nObserva: substring tiene el tipo Substring, no String. Esta es una diferencia importante. Substring es una "ventana" a la cadena original. No copia los datos, simplemente hace referencia a una parte de la memoria de la cadena original. Esto es súper eficiente, pero puede provocar fugas de memoria si la cadena original es grande y la subcadena es pequeña.
Para convertir un Substring en un String completo, simplemente usa el inicializador:
let newString = String(substring)\nprint(newString) // "Swift"\n\nAzúcar sintáctico: RangeExpression
\n\nEscribir index(offsetBy:) cada vez es tedioso. Afortunadamente, Swift permite usar formas más cortas con RangeExpression.
Operador ... (ClosedRange)
\nlet str = "¡Hola, Mundo!"\nif let range = str.range(of: "Mundo") {\n let mundoSubstring = str[range]\n print(mundoSubstring) // "Mundo"\n}\n\nRangos parciales (Partial Range)
\n¿Quieres tomar todo hasta un índice determinado o después de él? Fácil:
\nlet text = "Swift Programación"\nlet prefix = text[..<text.index(text.startIndex, offsetBy: 5)]\nprint(prefix) // "Swift"\n\nlet suffix = text[text.index(text.startIndex, offsetBy: 6)...]\nprint(suffix) // "Programación"\n\nObserva: prefix y suffix también son Substring.
Métodos incorporados: prefix, suffix, dropFirst, dropLast
\n\nSwift proporciona métodos convenientes que evitan el cálculo manual de índices. Devuelven Substring.
- \n
str.prefix(5)— primeros 5 caracteres. \n str.suffix(3)— últimos 3 caracteres.
Blogs
Book Recommendations
Leer también
PHP en 2025: por dónde empezar para principiantes — guía paso a paso