Inicio: prepara tu forma de aprender#
Este curso es material de estudio fundamentado en la observación empírica; no incluye una aplicación prefabricada que instalar, un proyecto de producto comercial ni un servicio en la nube que publicar. Avanza únicamente cuando puedas explicar y comprobar los comportamientos a nivel causal, no por el tiempo transcurrido o la cantidad de páginas leídas.
Para consultar definiciones formales a lo largo de este y otros módulos, apóyate en el glosario técnico.
Prerrequisitos y comprobaciones en Windows#
Necesitas una terminal de comandos, un editor de texto plano y la capacidad de inspeccionar archivos del sistema. La ruta inicial de Rust utiliza exclusivamente la biblioteca estándar; no hace falta instalar librerías externas ni herramientas complejas para comenzar.
En PowerShell, ejecuta los siguientes comandos para comprobar qué herramientas ya están disponibles en tu sistema:
rustc --version
cargo --version
node --version
npm --version
Estas órdenes consultan versiones registradas en tu variable de entorno PATH; no instalan, modifican ni actualizan ningún archivo en tu equipo. Si la terminal indica que algún comando no se reconoce, anota cuál falta y consulta la documentación oficial antes de decidir si deseas instalarlo. El curso no presupone una versión universal fija ni automatiza descargas globales. Una versión observada en una máquina específica tampoco garantiza compatibilidad universal en otros entornos.
- Para el primer tramo (Módulo 01): Basta con disponer de
rustc. Aprenderás a compilar archivos independientes directamente. - Para proyectos con dependencias (Módulo 02 en adelante):
cargoorganizará módulos, manifiestos y dependencias externas cuando sea estrictamente necesario. - Para el tramo de navegador (Módulo 03): Se utilizarán Node y npm para compilar TypeScript y ejecutar entornos de prueba frontend. No necesitas iniciar con Actix, PostgreSQL, React o un entorno de desarrollo integrado (IDE) específico.
Cuando desees ejecutar una práctica en tu máquina, sigue la guía de laboratorios opcionales en Windows. Dicha guía crea archivos únicamente en una carpeta privada de tu perfil, distingue comandos locales de aquellos que acceden a la red para descargar paquetes y no ejecuta instalaciones por ti.
Diccionario de herramientas y conceptos de estudio#
Para estudiar con rigor técnico y sin ambigüedades, este glosario desglosa desde primeros principios las diez herramientas y conceptos metodológicos centrales de este tramo:
1. Compilador (rustc)#
- Intuición cotidiana: Un traductor simultáneo sumamente estricto que lee una obra escrita en un lenguaje abstracto de alto nivel y la traduce a instrucciones mecánicas binarias que el procesador entiende, negándose a emitir una sola palabra si encuentra una sola contradicción lógica o gramatical en el texto original.
- Definición técnica precisa: Programa binario ejecutable que transforma código fuente escrito en lenguaje Rust (
.rs) en código máquina nativo (formato PE ejecutable.exeen Windows o binarios ELF en Linux), o en bibliotecas estáticas/dinámicas (.rlib,.dll). Realiza análisis léxico, análisis sintáctico (construcción del AST), análisis semántico de tipos, verificación estricta de préstamos (borrow checking) y optimización mediante la infraestructura LLVM. - Ejemplo en el sistema:
# Compile a single source file into a native Windows executable
rustc .\sample.rs -o .\sample.exe
- Lo que NO es: No es un intérprete que lee y ejecuta el código línea por línea en tiempo real (como el motor de Node.js o Python). Tampoco es un gestor de dependencias;
rustcsolo sabe procesar los archivos y bibliotecas que se le pasen explícitamente como argumentos de entrada.
2. Tiempo de compilación (Compile time) frente a Tiempo de ejecución (Runtime)#
- Intuición cotidiana:
- Tiempo de compilación: El arquitecto e ingenieros revisando los planos estructurales de un puente en la oficina, calculando cargas y tensiones con modelos matemáticos para asegurar que no colapse antes de poner el primer ladrillo.
- Tiempo de ejecución: El tráfico real de camiones cruzando el puente ya construido a 100 km/h bajo una lluvia torrencial.
- Definición técnica precisa:
- *Tiempo de compilación (Compile time):* Período durante el cual el código fuente es analizado, tipado y transformado en instrucciones de máquina por el compilador. Los errores detectados aquí impiden que se genere un ejecutable defectuoso.
- *Tiempo de ejecución (Runtime):* Fase en la que las instrucciones de máquina del binario generado son cargadas en la memoria RAM y ejecutadas instrucción por instrucción por la Unidad Central de Procesamiento (CPU).
- Ejemplo en código:
- Intentar sumar un entero y un texto (
let sum = 5 + "text";) es un error detectado en tiempo de compilación. - Intentar leer un archivo que fue borrado del disco por otro proceso mientras el programa corre es un evento que ocurre en tiempo de ejecución.
- Lo que NO es: No son intercambiables. Asumir que "si compila, no puede fallar nunca en tiempo de ejecución" es falso: un fallo de red o un disco lleno son eventos inevitables del entorno de ejecución que deben modelarse explícitamente en el diseño.
3. Biblioteca estándar (std)#
- Intuición cotidiana: El juego de herramientas básicas que viene incluido de fábrica en la maleta al comprar un automóvil: rueda de repuesto, llave inglesa y gato hidráulico, diseñadas con los más altos estándares del fabricante para funcionar con ese vehículo sin necesidad de comprar piezas adicionales.
- Definición técnica precisa: Conjunto de tipos fundamentales (
Option,Result,Vec,String), módulos de entrada/salida (std::io,std::fs), interfaces de concurrencia (std::sync,std::thread) y primitivas de memoria que acompañan oficialmente al compilador de Rust. Está disponible de forma predeterminada sin necesidad de declarar dependencias externas en ningún manifiesto. - Ejemplo en código:
// Standard library structures available out of the box
use std::collections::HashMap;
let mut registry: HashMap<u32, &'static str> = HashMap::new();
registry.insert(1, "Initialized");
- Lo que NO es: No es un paquete de terceros descargado de internet ni un framework pesado. No requiere conexión a la red ni gestor de paquetes para compilarse.
4. Crate#
- Intuición cotidiana: Una caja estandarizada de piezas de construcción sellada y etiquetada, lista para conectarse con otras cajas o funcionar de forma independiente como una máquina autónoma.
- Definición técnica precisa: La unidad mínima de compilación, empaquetado y distribución de código en Rust. Un crate puede ser un crate binario (que contiene una función
mainy produce un archivo ejecutable.exe) o un crate de biblioteca (que provee funciones, tipos y constantes reutilizables para que otros crates los consuman, compilando como un.rlib). - Ejemplo en el sistema: Al ejecutar
rustc sample.rs, el compilador trata asample.rscomo el archivo raíz (crate root) de un crate binario anónimo. - Lo que NO es: No es una simple carpeta o módulo suelto dentro de un archivo. Un crate contiene una jerarquía de módulos y posee un límite de visibilidad estricto determinado por la palabra clave
pub.
5. Cargo y Cargo.toml#
- Intuición cotidiana: El jefe de logística y compras de un taller: se encarga de leer la lista de materiales (
Cargo.toml), solicitar las herramientas necesarias a los almacenes oficiales, organizar el orden de ensamble y llamar al especialista (rustc) para que construya el producto final. - Definición técnica precisa:
cargoes el sistema oficial de gestión de paquetes y orquestación de compilación de Rust.Cargo.tomles su archivo de manifiesto estructurado en formato TOML donde se declaran los metadatos del paquete (nombre, versión, edición de Rust) y el árbol de dependencias externas con sus restricciones semánticas de versión. - Ejemplo en archivo (
Cargo.toml):
[package]
name = "actix-boundary-lab"
version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = "4"
- Lo que NO es:
cargono es el compilador.cargono sabe transformar sintaxis de Rust en código máquina; delega esa tarea invocando por debajo arustccon los argumentos y rutas de enlace correctas.
6. Arnés de pruebas (--test)#
- Intuición cotidiana: Una pista de pruebas especial en una fábrica donde un vehículo se somete a rampas empinadas, frenados bruscos y temperaturas extremas, equipada con sensores que registran si cada prueba pasó o falló antes de liberar el modelo.
- Definición técnica precisa: Modo de compilación de
rustcactivado mediante la bandera--test. Al compilar con esta bandera, el compilador ignora la funciónmainhabitual, busca todas las funciones anotadas con el atributo#[test], sintetiza internamente un ejecutable con un corredor de pruebas multihilo (test runner) y genera un informe estructurado que indica qué pruebas pasaron (ok), cuáles fallaron (FAILED) y los mensajes de pánico asociados. - Ejemplo en el sistema:
# Compile test harness and run it
rustc --test .\sample.rs -o .\sample-tests.exe
.\sample-tests.exe
- Lo que NO es: No es un framework externo ni una herramienta que requiera librerías de terceros; es una capacidad integrada nativamente en la arquitectura de
rustcy de la biblioteca estándar.
7. Ciclo TDD (RED - GREEN - REFACTOR)#
- Intuición cotidiana:
- Rojo: Pintar una diana en la pared donde detectamos que falta un clavo y comprobar que actualmente la pared está vacía.
- Verde: Colocar el clavo exacto en la diana hasta que la pintura quede cubierta.
- Refactorizar: Lijar y pulir la pared alrededor del clavo para que se vea impecable, asegurándonos de que el clavo no se mueva de su lugar.
- Definición técnica precisa: Metodología disciplinada de desarrollo de software conducida por pruebas automatizadas que se ejecuta en tres fases estrictas:
- RED (Rojo): Se escribe una prueba unitaria que modela un requisito y se ejecuta, verificando que falle con un diagnóstico preciso. Si la prueba pasa antes de implementar la solución, es inválida o tautológica.
- GREEN (Verde): Se escribe la cantidad mínima indispensable de código de producción para que la prueba pase exitosamente.
- REFACTOR (Refactorizar): Se reestructura el código para eliminar duplicaciones, clarificar abstracciones y mejorar el diseño, manteniendo las pruebas en ejecución constante para garantizar que ninguna funcionalidad observable se rompa.
- Ejemplo en el sistema: Escribir primero un test que espera que una función retorne un error al pasar una cadena vacía; ver cómo falla la aserción (
RED); agregar la condiciónif raw.is_empty()para que pase (GREEN); y finalmente reorganizar la lógica extrayendo una función auxiliar sin que la prueba deje de pasar (REFACTOR). - Lo que NO es: No es escribir cientos de líneas de código durante días y redactar algunas pruebas superficiales al final solo para cumplir una cuota de cobertura.
8. Límite (Boundary)#
- Intuición cotidiana: Una esclusa de desinfección en un laboratorio biológico: nadie entra del exterior sin pasar por la esclusa donde se eliminan contaminantes y se comprueban credenciales de bioseguridad.
- Definición técnica precisa: Interfaz arquitectónica que separa dos subsistemas con diferentes niveles de confianza, representación de datos o ciclos de vida (por ejemplo, el límite entre la red TCP y la memoria interna del servicio, o entre el código de servidor y el motor del navegador). En el límite se sitúan los serializadores y analizadores que rechazan datos deformados antes de que contaminen el núcleo del sistema.
- Ejemplo en código: La capa donde un JSON crudo entrante se valida contra una estructura estricta
CreateUserRequestantes de invocar los servicios internos. - Lo que NO es: No es una simple separación visual de archivos en carpetas. Si los datos no tipados o no saneados viajan sin restricción por todo el sistema, el límite arquitectónico no existe.
9. clone() (duplicación en memoria heap)#
- Intuición cotidiana: En lugar de prestarle tu libro a un compañero de clase para que lo consulte, vas a una fotocopiadora, copias página por página todo el libro, encuadernas el nuevo tomo y se lo regalas para que pueda rayarlo sin afectar el tuyo.
- Definición técnica precisa: Método del trait
Cloneen Rust que ejecuta una copia explícita y completa de los recursos que posee una estructura de datos. Para estructuras dinámicas comoStringoVec<T>, implica reservar un nuevo bloque de memoria en el montículo (heap), copiar todos los bytes elemento por elemento y crear un nuevo descriptor independiente en la pila (stack). - Ejemplo en código:
let original = String::from("Critical invariant");
// Explicit heap allocation: copies all underlying bytes
let duplicate = original.clone();
- Lo que NO es: No es una operación gratuita ni un simple paso de puntero. Utilizar
clone()de forma indiscriminada cada vez que el compilador reporta un conflicto de préstamos destruye la eficiencia de la memoria y suele indicar una evasión del diseño de propiedad adecuado.
10. unwrap() y panic! (extracción insegura y aborto de pila)#
- Intuición cotidiana: Abrir una caja de encomienda con una palanca de demolición asumiendo ciegamente que contiene un regalo frágil; si la caja resulta estar vacía, la palanca se estrella contra el suelo, salta una alarma de emergencia en el edificio y se evacúa a todo el personal.
- Definición técnica precisa:
unwrap(): Método de conveniencia enOption<T>yResult<T, E>. Si el valor esSome(v)uOk(v), extraev. Si esNoneoErr(e), invoca forzosamente a la macropanic!.panic!: Mecanismo de parada de emergencia en Rust. Detiene la ejecución normal del hilo actual, imprime un mensaje de diagnóstico con la ubicación del código y, por defecto, inicia el desmantelamiento de la pila (stack unwinding), liberando recursos antes de terminar el hilo o abortar el proceso.- Ejemplo en código:
let input: Option<i32> = None;
// Dangerous extraction: triggers a panic at runtime because the value is None
let value = input.unwrap();
- Lo que NO es: No es una estrategia válida de manejo de errores en software de producción o backend. Los errores previsibles del entorno (como un JSON malformado o un archivo inexistente) deben modelarse como variantes de
Resulty manejarse con control de flujo explícito (match,if let, o el operador?), nunca mediante pánicos no controlados.
Fundamentos del método de trabajo#
Para construir disciplina de ingeniería, es imperativo entender las razones causales detrás de las prácticas exigidas en este curso:
¿Por qué empezamos con rustc en crudo antes de usar Cargo?#
Muchas rutas de aprendizaje introducen cargo new desde el minuto uno. Aunque conveniente, esta abstracción temprana crea una "caja negra": los estudiantes asumen que Cargo es el lenguaje o que compilar requiere obligatoriamente una estructura compleja de archivos de configuración.
- Desmitificación de la herramienta: Al ejecutar directamente
rustc sample.rs -o sample.exe, observas con tus propios ojos que Rust es, en su esencia más pura, un compilador que toma un archivo de texto con código fuente y genera un binario ejecutable nativo para el sistema operativo. - Reducción radical de la sobrecarga cognitiva: Al inicio no necesitas preocuparte por manifiestos
Cargo.toml, resoluciones de bloqueos enCargo.lock, carpetastarget/de cientos de megabytes ni problemas de red al descargar dependencias. - Comprensión de los mecanismos del compilador: Aprender qué hace la bandera
--testdirectamente enrustcte permite entender cómo se instrumenta un arnés de pruebas antes de que Cargo oculte ese proceso detrás del comandocargo test.
¿Por qué presenciar el fallo en rojo (RED) es imprescindible?#
Un error cognitivo común entre desarrolladores novatos es escribir el código y la prueba al mismo tiempo, ejecutar la suite, ver que todo sale en verde y asumir que el software funciona. Este procedimiento adolece de un grave defecto epistemológico: la prueba podría ser vacua o tautológica.
- El peligro de las pruebas vacuas: Si cometes un error lógico en la aserción (por ejemplo, escribes un condicional que nunca se cumple o comparas una variable consigo misma), la prueba pasará siempre, incluso si el código de producción está completamente roto o vacío.
- La garantía del estado RED: Ver la prueba fallar en rojo antes de implementar el código de producción te otorga dos certezas fundamentales:
- Demuestra empíricamente que la prueba se está ejecutando realmente y que no está siendo ignorada por el arnés.
- Demuestra que la aserción es sensible y capaz de detectar la ausencia de la funcionalidad esperada, reportando el fallo con un mensaje claro y en la línea correcta.
¿Por qué aceptar ciegamente .clone() o .unwrap() sugeridos por IA oculta defectos estructurales?#
Los modelos de lenguaje tienden a optimizar para una sola métrica superficial: hacer que el código compile sin que el usuario reciba un mensaje de error inmediato. Cuando un estudiante consulta a una IA sobre un error del borrow checker o un desajuste de tipos con Result, la solución más común propuesta por el modelo es insertar .clone() o .unwrap().
- El daño de
.clone()indiscriminado: Rust impone reglas estrictas de propiedad para garantizar que nunca existan dos punteros modificando la misma memoria o accediendo a memoria liberada. Al clonar el dato, creas una copia entera de los bytes en el heap solo para sortear las advertencias del compilador. El código compila, pero has destruido el modelo de memoria del sistema, introduciendo penalizaciones de rendimiento y evadiendo la comprensión de los préstamos (borrows) y referencias. - El daño de
.unwrap(): Utilizar.unwrap()transforma un fallo manejable (como una entrada de usuario incorrecta) en una bomba de tiempo en tiempo de ejecución. El código compila sin quejas, pero tu servicio backend colapsará catastróficamente con un panic! en cuanto un cliente envíe un dato imprevisto.
Método de estudio de cada lección#
Sigue rigurosamente este ciclo de trabajo de cinco pasos en cada lección del curso:
flowchart TD
Step1["1. Leer objetivos e invariantes"] --> Step2["2. Trazar modelo mental y flujo de memoria"]
Step2 --> Step3["3. Formular predicción explícita por escrito"]
Step3 --> Step4["4. Ciclo TDD: Fallo observable (RED) -> Solución mínima (GREEN) -> Refactor"]
Step4 --> Step5["5. Auditar y registrar evidencia observable en PROGRESS.md"]
- Lectura y fundamentación: Lee el objetivo y las restricciones conceptuales de la lección. Si aparece un término técnico que no puedas explicar a nivel de hardware o datos, haz una pausa y consulta el glosario técnico.
- Modelado previo: Dibuja o describe en papel el flujo de datos antes de ver la solución. En Rust, traza punteros, transferencias de propiedad y ámbitos de vida en la pila. En la web, traza la frontera de serialización entre el navegador y el backend.
- Predicción escrita: Formula explícitamente qué salida generará el compilador o la terminal antes de presionar Enter. Si no puedes predecir la salida, aún estás operando por ensayo y error.
- Ciclo de práctica y falsación: Trabaja en un archivo temporal propio en tu carpeta de laboratorio. Escribe primero una prueba que falle (RED), implementa el cambio mínimo estricto para que pase (GREEN), y limpia el diseño sin alterar el comportamiento observable (REFACTOR).
- Registro de evidencia: Transcribe los resultados concretos y tus reflexiones causales en tu bitácora de PROGRESS.md.
Protocolo de tutoría con IA#
Si decides interactuar con modelos de lenguaje como asistentes de estudio, utilízalos como un examinador socrático exigente, nunca como un redactor automático de tus soluciones:
- Protocolo de consulta rigurosa: Antes de formular una pregunta a una IA, ten documentados cuatro elementos:
- Tu predicción inicial y la hipótesis de por qué esperabas ese comportamiento.
- El comando exacto ejecutado en la terminal.
- El diagnóstico íntegro del compilador o runtime (sin recortar líneas ni códigos de error).
- La regla de invariante o límite que sospechas que se está violando.
- Solicitud de pistas en lugar de soluciones: Pide a la IA preguntas orientadoras que te ayuden a identificar en qué línea se transfirió la propiedad de un dato o qué contrato de tipos no se está cumpliendo. Solicita una solución en código únicamente después de haber intentado una explicación causal por tu cuenta.
- Auditoría obligatoria de código generado: Si una IA sugiere utilizar
.clone(),.unwrap(), una librería de terceros o un patrón de diseño complejo, exige que justifique: - ¿Qué asignaciones de memoria adicionales introduce en la pila o en el heap?
- ¿Qué garantías de seguridad o invariantes se pierden con ese atajo?
- ¿Cómo se resolvería el mismo problema respetando el ownership idiomático de Rust sin duplicar datos?
- Seguridad y privacidad: Jamás compartas claves de acceso, contraseñas, tokens de autenticación ni datos sensibles en las consultas.
Preguntas de comprensión profunda sobre el método de trabajo#
Dedica tiempo a reflexionar sobre estas cinco preguntas antes de pasar a la primera lección de código. Cada pregunta incluye ejes de análisis y una guía de razonamiento para evaluar la solidez de tu método:
Pregunta 1: Mecánica de la compilación directa frente a orquestación de paquetes#
Un colega afirma: "Aprender a invocar rustc directamente desde la terminal de Windows es una pérdida de tiempo irrelevante porque en el mundo profesional todo el mundo usa cargo build".
- Ejes de análisis:
- ¿Qué responsabilidades corresponden exclusivamente al compilador (
rustc) y cuáles son exclusivas del orquestador (cargo)? - ¿Qué ocurre internamente cuando
cargo buildse ejecuta en un proyecto simple? ¿Qué comandos reales envía Cargo al sistema operativo? - ¿Cómo te ayuda conocer las banderas directas de
rustc(como--testo-o) a entender el funcionamiento interno de herramientas de integración continua o generadores de binarios mínimos?
- Guía de razonamiento: Quien solo sabe utilizar herramientas de alto nivel queda completamente indefenso cuando la herramienta de abstracción falla o produce un error de configuración. Entender que Cargo es un envoltorio que ejecuta
rustcte da claridad mental sobre la verdadera cadena de valor de compilación y enlace.
Pregunta 2: Anatomía de una aserción y el valor del estado RED#
Escribes una prueba unitaria para una función matemática que calcula el área de un círculo. Ejecutas el arnés de pruebas y la terminal reporta test area_calculation ... ok. Sin embargo, al revisar el código de la prueba, descubres que habías escrito assert!(true); por descuido.
- Ejes de análisis:
- ¿Por qué el arnés de pruebas reportó éxito rotundo si la función matemática ni siquiera fue ejecutada?
- ¿Cómo evita la disciplina del paso inicial en rojo (RED) que aserciones triviales o caminos de código inalcanzables se hagan pasar por pruebas válidas?
- ¿Qué información técnica indispensable aporta la macro
assert_eq!(left, right)en comparación con un genéricoassert!(left == right)cuando una aserción falla?
- Guía de razonamiento: Una prueba solo demuestra fiabilidad si previamente demostró su capacidad de fallar cuando la condición no se cumplía. La macro
assert_eq!captura e imprime los valores textuales de los operandos izquierdo y derecho implementando el traitstd::fmt::Debug, lo que permite un diagnóstico inmediato sin tener que depurar manualmente.
Pregunta 3: El costo oculto de .clone() como vía de escape al borrow checker#
Al intentar compilar un programa donde una variable de tipo String se utiliza en dos funciones consecutivas, el compilador emite el error E0382: use of moved value. Al consultar a un foro, alguien te aconseja: "Ponle .clone() a la variable en la primera llamada y ya compila".
- Ejes de análisis:
- ¿Qué ocurrió en la memoria del programa para que la primera llamada se apropiara del dato original?
- ¿Qué impacto medible tiene llamar a
.clone()sobre unStringde 10 megabytes que se ejecuta 1,000 veces por segundo en un bucle? - ¿Cuál es la alternativa idiomática en Rust para permitir que la primera función lea los datos del
Stringsin quitarle la propiedad a la función principal?
- Guía de razonamiento: Invocar
.clone()duplica la memoria en el heap y realiza una llamada al asignador del sistema operativo. El borrow checker no te estaba impidiendo programar; te estaba advirtiendo de una transferencia no intencionada de propiedad. La solución natural y eficiente es pasar un préstamo inmutable por referencia (&stro&String), manteniendo un único bloque de memoria compartido de forma segura.
Pregunta 4: La falacia del código "que funciona" generado por IA#
Una herramienta de IA generativa te ofrece una solución de 20 líneas para un problema de parsing de fechas. Pegas el código en tu editor, compila sin errores y arroja el formato esperado para la fecha de hoy.
- Ejes de análisis:
- ¿Qué pruebas de frontera (edge cases) debes aplicar antes de considerar que el código es correcto (ej. años bisiestos, cambios de huso horario, cadenas con caracteres no numéricos, valores nulos)?
- ¿Cómo verificas si el código generado incluye dependencias ocultas o conversiones innecesarias que penalicen la memoria?
- Si ocurre una caída en producción originada por una de esas 20 líneas, ¿cómo explicarás al equipo la causa raíz del fallo si no entendiste cada instrucción al momento de integrarla?
- Guía de razonamiento: La sintaxis compilable es la condición más básica y superficial del software. Un código que no puedes justificar línea por línea es una deuda técnica y un riesgo de seguridad latente. La verdadera prueba de dominio es tu capacidad de someter el código a estrés y defender su idoneidad arquitectónica.
Pregunta 5: Transiciones en los límites del sistema e incertidumbre tipada#
Un programa lee un número entero desde el teclado del usuario utilizando std::io::stdin().read_line(&mut buffer). El programador novato intenta usar inmediatamente el buffer como un número entero sin ninguna conversión ni verificación.
- Ejes de análisis:
- ¿En qué formato físico viajan los datos ingresados por el usuario desde el teclado y qué caracteres adicionales invisibles (saltos de línea
\r\n) acompañan a la entrada? - ¿Por qué la operación de lectura puede fallar a nivel del sistema operativo y por qué el parseo de texto a número entero puede fallar de forma independiente?
- ¿Cómo utiliza Rust el sistema de tipos algebraicos (
Result<T, E>) para forzarte a manejar ambos puntos de incertidumbre por separado antes de permitirte operar con el número?
- Guía de razonamiento: El mundo exterior a nuestro proceso es caótico y no garantiza conformidad de tipos. Rust prohíbe la suposición ciega mediante tipos explícitos: la lectura devuelve un
io::Result<usize>y el parseo devuelve unParseIntError. El sistema de tipos actúa como el guardián inquebrantable de la frontera.
Próximo paso#
Avanza con paso firme abriendo la Lección 01: Tipos y flujo de control. Si los comandos de Rust aún no están instalados en tu terminal, puedes estudiar los modelos mentales y diagramas, pero no registres ninguna práctica como completada en PROGRESS.md hasta que hayas ejecutado y verificado personalmente los comandos en tu laboratorio local.