Cómo incluir un módulo desde otro archivo en Rust: de principiante a usuario seguro
\n\n¿Alguna vez ha escrito código en Rust y de repente se ha dado cuenta de que su main.rs se está convirtiendo en un monstruo gigante de 500 líneas? ¿Le suena familiar? O quizás está empezando a aprender Rust y quiere entender cómo organizar correctamente el código, dividiéndolo en varios archivos. La pregunta "How can I include a module from another file from the same project?" es una de las más populares en Stack Overflow, y con razón. El sistema de módulos de Rust es a la vez potente y... un poco poco intuitivo para los principiantes.
En este artículo, lo desglosaremos todo de principio a fin: cómo crear un módulo, cómo importarlo, qué trampas hay y cómo no pisar el rastrillo. ¡Vamos allá!
\n\n¿Por qué los módulos en Rust no son simplemente un "include"?
\n\nSi viene de Python o JavaScript, está acostumbrado a import o require. En Rust, es un poco diferente. Aquí no hay una mágica "toma el archivo y úsalo". En su lugar, Rust utiliza un sistema de módulos declarativo. Debe decirle explícitamente al compilador: "Oye, este archivo es parte de mi proyecto, y así es como se llama".
La regla principal que debe recordar es: cada archivo es un módulo, pero no todos los módulos son un archivo. Suena como un acertijo, ¿verdad? Ahora lo entenderemos.
\n\nEstructura del proyecto: por dónde empezar
\n\nSupongamos que tiene un proyecto con esta estructura:
\n\nmy_project/\n├── Cargo.toml\n├── src/\n│ ├── main.rs\n│ ├── greetings.rs\n│ └── utils/\n│ ├── mod.rs\n│ └── helpers.rs\n\nAquí, greetings.rs es un módulo simple, y utils/ es una carpeta con un módulo. Aprendamos a importarlos.
Método 1: Importar un archivo-módulo simple
\n\nEl caso más básico. Tiene greetings.rs con una función:
// greetings.rs\npub fn say_hello() {\n println!("¡Hola desde el módulo greetings!");\n}\n\nPara usar este módulo en main.rs, necesita hacer dos cosas:
- \n
- Declarar el módulo con la palabra clave
mod\n - Importar los elementos necesarios con
use\n
// main.rs\nmod greetings; // declaramos el módulo\n\nuse greetings::say_hello; // importamos la función\n\nfn main() {\n say_hello(); // la usamos\n}\n\n¡Eso es todo! Rust busca automáticamente el archivo greetings.rs en la misma carpeta donde se encuentra main.rs. Si encuentra el archivo, el módulo está importado.
Importante: la función say_hello está marcada como pub. Si olvida pub, el compilador dirá que la función es privada e inaccesible desde fuera. Este es uno de los errores más comunes de los principiantes.
Método 2: Módulo en una carpeta (mod.rs o lib.rs)
\n\nCuando su proyecto crece, es conveniente agrupar los módulos en carpetas. Para ello, se utiliza el archivo mod.rs dentro de la carpeta. Sirve como "punto de entrada" al módulo.
Creemos la carpeta utils/ y dentro de ella mod.rs:
// utils/mod.rs\npub mod helpers; // declaramos el módulo anidado\n\nAhora creemos helpers.rs:
// utils/helpers.rs\npub fn do_something() {\n println!("Haciendo algo útil");\n}\n\nEn main.rs lo importamos así:
// main.rs\nmod utils; // declaramos el módulo utils (busca utils/mod.rs)\n\nuse utils::helpers::do_something;\n\nfn main() {\n do_something();\n}\n\nObserve: mod utils; le dice a Rust que busque utils/mod.rs o utils.rs. Si encuentra mod.rs — perfecto, si encuentra utils.rs — también funciona. Pero no puede tener ambos archivos al mismo tiempo — el compilador se confundirá.