CodeGym /Cursos /Swift SELF /Cadenas en Swift: String, interpolacion "\(...)"

Cadenas en Swift: String, interpolacion "\(...)"

Swift SELF
Nivel 2, Lección 2
Disponible

1. Fundamentos de las cadenas en Swift

Si los numeros son aquello en lo que la programa piensa, entonces las cadenas son aquello con lo que la programa habla con la persona. Casi cualquier tarea de consola acaba reduciendose a que debes mostrar el resultado en el formato correcto: con palabras, con espacios, a veces con signos : o =. Y aunque la tarea sea puramente matematica, aun asi imprimes texto.

En Swift, el tipo de cadena se llama String. Almacena una secuencia de caracteres, es decir, «texto». Un detalle importante: una cadena es datos, igual que un numero. Se puede guardar en una variable, pasarla mas adelante por el codigo, «montarla» a partir de fragmentos y luego mostrarla.

La cadena mas simple es un literal de cadena, es decir, texto entre comillas:

let title = "LibraryCLI"
print(title) // LibraryCLI

Aqui title es una constante de tipo String. Sin magia: solo un valor que almacena texto.

Literales de cadena: "..." y que se considera un simbolo

Cuando ves "Hello", la mente del desarrollador suele pensar: «bueno, eso es solo una palabra». Pero para la programa es un conjunto de simbolos. Y la programa no sabe adivinar «espacios correctos» o «donde poner una coma» hasta que tu mismo lo escribes. Un espacio tambien es un simbolo. Un punto tambien es un simbolo. Incluso dos espacios seguidos son dos simbolos (y a veces eso puede romper la comprobacion de una respuesta en las tareas).

En tareas sencillas de nivel 2 nos basta con recordar algunas reglas practicas. La cadena se escribe entre comillas dobles, dentro puedes guardar cualquier simbolo normal, y si quieres mostrar una frase bonita, debes anadir explicitamente los espacios y la puntuacion donde haga falta.

Por ejemplo, comparemos «bonito» y «pegado»:

let firstName = "Ivan"
let lastName = "Petrov"

let good = firstName + " " + lastName
print(good) // Ivan Petrov

let bad = firstName + lastName
print(bad)  // IvanPetrov

Fijate: " " es una cadena de un solo espacio. Si, el espacio es tan importante que tiene su propia cadena.

Concatenacion mediante +: pegamos cadenas como LEGO

La palabra «concatenacion» suena como si fuera un hechizo del mundo de los compiladores, pero en realidad significa «unir cadenas». En Swift, las cadenas se pueden sumar con el operador +. El resultado sera una nueva cadena.

Aqui conviene pensar en las cadenas como piezas de LEGO: tienes fragmentos de texto y montas con ellos una sola frase. Pero, igual que en LEGO, si olvidas una pieza (por ejemplo un espacio), la construccion queda rara.

Ejemplo: generamos un mensaje claro sobre el numero de libros. Sin entrada por ahora, solo como practica de formato.

let libraryName = "City Library"
let booksCount = 12

let message = "Library: " + libraryName + ", books: " + "\(booksCount)"
print(message) // Library: City Library, books: 12

Espera. ¿Y que es eso de "\(booksCount)"? Eso ya es interpolacion, la veremos un poco mas abajo. Por ahora, fijate en lo importante: el operador + sabe unir cadena con cadena, pero no «cadena con numero».

Por que "x=" + 10 no compila

Una situacion muy tipica de principiante: quieres mostrar «x=10», escribes "x=" + 10, y Swift dice: «no». La razon es simple e incluso util: + no es un «cinta adhesiva universal», sino un operador que debe entender exactamente que esta sumando.

Una cadena es String. Un numero es Int. Y el compilador no quiere adivinar como convertir exactamente ese numero en texto. Por eso una expresion como str + 1 le parece sospechosa a Swift, y el compilador da un error porque los tipos no coinciden. Esta situacion incluso se presenta como ejemplo de como el compilador busca el problema en la expresion str + 1 y de por que a una persona le queda claro enseguida que no va bien, mientras que el compilador necesita mostrarlo mediante el sistema de restricciones de tipos.

En la practica, eso significa una cosa: no se pueden sumar directamente String e Int. Hay que convertir explicitamente el numero en cadena (mas adelante aprenderemos a hacerlo mediante entrada y conversiones), o utilizar la interpolacion de cadenas.

Para no romper la compilacion, la cadena «mala» puede dejarse como comentario, para recordar que asi no se debe hacer:

let x = 10
let prefix = "x="

// let text = prefix + x   // asi no: String + Int
let okText = prefix + "\(x)"
print(okText) // x=10

Ahora esto parece un apaño. Pero en realidad es una pista hacia la siguiente seccion: la interpolacion es nuestra herramienta principal para estas tareas.

Interpolacion "\(...)": la forma mas amable de insertar valores

La interpolacion de cadenas en Swift consiste en que dentro de una cadena escribes \(algo) y Swift inserta con cuidado ese valor, convirtiendolo en texto. Para un principiante, suele ser lo mas agradable: menos pegado manual, menos espacios olvidados, y el codigo se lee como una frase normal.

Se ve asi:

let bookTitle = "Dune"
let pages = 412

let text = "Book: \(bookTitle), pages: \(pages)"
print(text) // Book: Dune, pages: 412

Fijate en la sensacion de «esto se lee como una frase». Esa es precisamente la cualidad que convierte la interpolacion en el metodo preferido de formateo en la mayoria de tareas.

Otra ventaja importante: en la interpolacion no solo puedes insertar Int, sino en general cualquier valor que se imprima correctamente. Y ya sabemos imprimirlos, porque print(...) es nuestra herramienta basica.

Interpolacion de expresiones: \(a + b) y «mini-formulas» en el texto

Cuando ves por primera vez "\(a + b)", puede parecer que Swift empieza a «ejecutar codigo dentro de la cadena». Y asi es: dentro de \(…) se puede escribir una expresion, y esta se evaluara, mientras que el resultado se insertara en la cadena.

Esto es superutil para tareas en las que hay que mostrar no solo un numero, sino tambien una explicacion: «3 + 4 = 7». Con concatenacion se hace de forma mas larga y es facil equivocarse. Con interpolacion, queda limpio.

let a = 3
let b = 4

let line = "\(a) + \(b) = \(a + b)"
print(line) // 3 + 4 = 7

Observa lo bien que se ve la estructura del resultado. Ese codigo se puede revisar facilmente con la vista, y eso en programacion es casi un superpoder.

Y si: este es justo el momento en que puedes «meter matematica en el texto» de forma legal y sentirte un poco mago, pero sin pasarte.

Pequena refactorizacion: la legibilidad importa mas que «una sola linea»

Al principio apetece mucho escribirlo todo «en una sola linea», porque parece mas «profesional». En la practica, profesional es cuando dentro de una semana entiendes tu propio codigo sin una expedicion arqueologica.

Por eso una regla util: si una cadena se construye a partir de varias partes, sobre todo si hay numeros y expresiones, no temas usar let intermedios. Eso no es «codigo de mas», es una forma de cuidar a quienes van a leer ese codigo.

Comparacion. Version «demasiado apretada»:

let currentPage = 37
let totalPages = 120
print("Progress: \(currentPage)/\(totalPages) (\(currentPage * 100 / totalPages)%)")

Version mas bonita:

let currentPage = 37
let totalPages = 120

let percent = currentPage * 100 / totalPages // division entera, la parte decimal se descarta
let text = "Progress: \(currentPage)/\(totalPages) (\(percent)%)"
print(text) // Progress: 37/120 (30%)

En la segunda version es mas facil entender donde se calcula cada cosa, y tambien es mas facil corregirlo si cambias la formula. Y si, fijate en la «entereza»: percent resulto ser Int, porque trabajamos con Int.

2. Mini-aplicacion: imprimimos el estado de una «mini-biblioteca»

Para que los ejemplos no sean un conjunto de cadenas sueltas, vamos a seguir desarrollando una pequena aplicacion de consola de prueba. Que sea una «mini-biblioteca» (un antepasado muy temprano de nuestro futuro proyecto CLI): la programa todavia no lee entrada ni guarda datos, solo imprime de forma bonita el estado: nombre de la biblioteca, libro actual y progreso de lectura.

Nuestro objetivo aqui no es «hacer una aplicacion util», sino entrenar la habilidad de convertir numeros y datos en una salida de texto limpia, sin perder espacios ni sentido.

Empezamos por lo basico: definimos los datos y mostramos un encabezado limpio.

let appName = "MiniLibrary"
let version = 1

let header = "\(appName) v\(version)"
print(header) // MiniLibrary v1

Fijate: v\(version) es un patron tipico, y se lee muy bien.

Ahora anadimos «datos del libro» y componemos una bonita linea de informe. Nos haran falta tanto String como Int.

let bookTitle = "Clean Code"
let currentPage = 57
let totalPages = 464

let progress = "\(currentPage)/\(totalPages)"
print("Now reading: \(bookTitle) — \(progress)") // Now reading: Clean Code — 57/464

El simbolo — (guion largo) tambien es simplemente un caracter de la cadena. Swift no protesta si imprimes texto humano normal.

Anadimos el porcentaje usando la aritmetica de Int de la leccion anterior:

let currentPage = 57
let totalPages = 464

let percent = currentPage * 100 / totalPages
let line = "Progress: \(percent)%"
print(line) // Progress: 12%

Y ahora compongamos el «informe final» de una forma mas legible: fragmentos separados en let, y luego la cadena final.

let libraryName = "City Library"
let bookTitle = "Clean Code"
let currentPage = 57
let totalPages = 464

let percent = currentPage * 100 / totalPages
let report = "Library: \(libraryName). Book: \(bookTitle). \(percent)% read."
print(report) // Library: City Library. Book: Clean Code. 12% read.

Por ahora parece modesto, pero esa es precisamente la habilidad que luego salva en tareas reales: haces que la salida sea predecible, comprensible y «como en el enunciado».

Esquema: como construimos el texto

A veces conviene ver el proceso como una pequena cadena de montaje:

flowchart LR
    A["Datos (Int/String)"] --> B["Formulas (Int)"]
    B --> C["Interpolacion en String"]
    C --> D["print(...)"]

En esta leccion estamos entrenando sobre todo el nodo C: convertir datos en texto.

3. Errores tipicos al trabajar con cadenas

Error #1: espacios olvidados al concatenar.
Cuando pegas cadenas mediante +, es facil obtener "IvanPetrov" en lugar de "Ivan Petrov". El problema no es Swift, sino que el espacio es un simbolo mas, como una letra. Una buena forma de solucionarlo es usar mas la interpolacion y, si aun asi concatenas, anadir explicitamente " " alli donde por sentido deba haber un espacio.

Error #2: intentar sumar una cadena y un numero con el operador +.
Una expresion como "x=" + 10 no compila, porque + no sabe convertir automaticamente Int a String. Desde el punto de vista del sistema de tipos, son mundos realmente distintos, y el ejemplo str + 1 es la situacion clasica en la que el compilador dice honestamente «el tipo no es el correcto». La mejor solucion en esta fase es la interpolacion: "x="\(10).

Error #3: convertir la salida en un «fideo» de + + +.
A veces el principiante empieza a construir una cadena asi: "a=" + "\(a)" + ", b=" + "\(b)" + ... — y al cabo de un minuto ya nadie entiende cuantas comillas hay ni donde se perdio la coma. La interpolacion es mucho mas limpia: "a="\(a), b=\(b). Si la cadena sigue siendo larga, dividela en let intermedios.

Error #4: esperar que la programa «adivine» la puntuacion.
Una pequena distraccion frecuente: olvidaste dos puntos, un punto, una coma o un espacio al final, y la respuesta no se da por valida. Para una persona eso es «pero si se entiende», mientras que para el sistema de comprobacion es un texto completamente distinto. Trata las cadenas como un contrato exacto: lo que imprimes es lo que cuenta.

Error #5: complicar demasiado pronto e intentar «ponerse profundo con las cadenas».
Swift, efectivamente, trata las cadenas con seriedad, porque el texto puede ser mas complejo de lo que parece (unicode, caracteres compuestos, etc.), y en la documentacion se subraya que la cadena en Swift esta orientada a la percepcion humana de los caracteres. Pero en nuestro nivel eso no es motivo para entrar en panico: hoy basta con dominar con seguridad las comillas, + y "\(...)", y todo lo demas llegara mas tarde, cuando exista una necesidad real.

1
Tarea
Swift SELF, nivel 2, lección 2
Bloqueada
Placa del visitante
Placa del visitante
1
Tarea
Swift SELF, nivel 2, lección 2
Bloqueada
Encabezado de la versión
Encabezado de la versión
1
Tarea
Swift SELF, nivel 2, lección 2
Bloqueada
Fórmulas escolares
Fórmulas escolares
1
Tarea
Swift SELF, nivel 2, lección 2
Bloqueada
Progreso de lectura
Progreso de lectura
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION