Históricamente, Rust ha sido diseñado desde el principio como un lenguaje para escribir programas de sistema escalables y confiables. El sistema de módulos fue creado para un estricto aislamiento de los espacios de nombres, la separación del código y la organización de grandes proyectos sin conflictos de nombres. Los módulos permiten estructurar el código, ocultar los detalles de implementación y gestionar una API pública.
El problema radica en que a medida que el proyecto crece, surge la cuestión del aislamiento de los componentes, el uso compartido del código y la gestión de la visibilidad. Los errores a menudo están relacionados con el mal uso de las palabras clave pub, pub(crate), así como con la falta o la incorrecta organización de la estructura de directorios y archivos.
Solución: en Rust, un módulo se declara con la palabra clave mod; los archivos y directorios estructuran el espacio de nombres, enfatizando la jerarquía. Todo es privado por defecto, y las palabras clave pub, pub(crate), pub(super) permiten gestionar la visibilidad. El uso correcto de las exportaciones, alias y una división adecuada del proyecto en módulos hacen que el código sea escalable, mantenible y seguro.
Ejemplo de código:
// src/lib.rs mod network; pub use network::client::Client; // src/network/mod.rs pub mod client; // src/network/client.rs pub struct Client { pub name: String, }
Características clave:
¿Qué ocurrirá si la estructura del directorio no coincide con las definiciones de los módulos?
El código no se compilará: Rust espera una correspondencia estricta entre archivos y módulos (por ejemplo, si se declara mod foo, debe existir el archivo foo.rs o el directorio foo/mod.rs).
¿Puede pub(crate) ser utilizado para ocultar la implementación de los consumidores externos, pero estar disponible para todos los módulos dentro del crate?
Sí, pub(crate) hace que el elemento sea visible en cualquier módulo del mismo crate, pero invisible para proyectos externos que utilizan este crate como dependencia.
¿Cómo importar funciones de un módulo anidado profundamente en el archivo raíz sin reexportarlos públicamente (pub use)?
A través de una referencia directa en la jerarquía: crate::module::submodule::function. Sin pub use, solo estarán disponibles dentro del crate.
En el proyecto, el módulo de red contiene todos los componentes del servidor, cliente, analizador de protocolos en un solo archivo network.rs. Todo se declara como pub, para pruebas se conecta directamente el código interno. Con el tiempo, aumenta la conectividad innecesaria y se vuelve difícil separar la interfaz pública de la implementación.
Ventajas:
Desventajas:
Network se divide en submódulos: client, server, protocol. Solo se exportan interfaces públicas desde network, la API es compacta, los detalles están encapsulados. Las pruebas para cada módulo están aisladas.
Ventajas:
Desventajas: