En Rust, la palabra clave use no “importa” código en el sentido tradicional de otros lenguajes; su función es crear un alias local para una ruta (path) específica dentro del ámbito (scope) actual. Esto permite evitar la escritura repetitiva de rutas largas y facilita la legibilidad. El sistema de rutas de Rust se basa en tres pilares: crate (la raíz del proyecto), self (el módulo actual) y super (el módulo padre).

El uso de llaves {} permite agrupar múltiples elementos de un mismo módulo, como use std::io::{Read, Write};, lo que mantiene el código limpio. Cuando dos elementos de distintos módulos comparten el mismo nombre, se utiliza la palabra clave as para renombrar uno de ellos, evitando colisiones de nombres. Por ejemplo, si tienes un Procesador en dos módulos distintos, puedes importarlos como ProcesadorA y ProcesadorB.

Un patrón esencial en el diseño de bibliotecas es la reexportación mediante pub use. Esto permite organizar el código internamente en múltiples archivos y submódulos para mantener el orden, pero exponer una API pública plana y coherente hacia el usuario. Sin la reexportación, el usuario de tu librería tendría que conocer tu estructura interna de archivos para acceder a un tipo, lo cual rompe el principio de encapsulamiento.

Se debe evitar el uso de glob imports (use modulo::*) en código de producción. Aunque son convenientes en tests, en la lógica principal introducen ambigüedad: no sabes exactamente qué elementos se han traído y cualquier cambio en la librería original podría introducir colisiones de nombres inesperadas que impidan la compilación.

// Definición de un módulo interno con estructura compleja
mod interna {
    pub struct Datos;
    pub struct Config;

    pub mod utilidades {
        pub struct Herramienta;
    }
}

// Módulo externo que simula una dependencia con nombres duplicados
mod externa {
    pub struct Herramienta;
}

// Módulo de la API pública que organiza y expone lo necesario
pub mod api {
    // 1. Reexportación: El usuario verá 'api::Datos' en lugar de 'interna::Datos'
    pub use crate::interna::Datos;

    // 2. Importación agrupada
    use crate::interna::Config;
    use crate::interna::utilidades::Herramienta;

    // 3. Uso de 'as' para evitar colisiones entre la herramienta interna y la externa
    use crate::externa::Herramienta as HerramientaExterna;
    use crate::interna::utilidades::Herramienta as HerramientaInterna;

    pub fn ejecutar_demo() {
        let _d = Datos;
        let _he = HerramientaExterna;
        let _hi = HerramientaInterna;
        println!("Demo ejecutada con éxito");
    }
}

// Módulo de pruebas que utiliza 'super'
mod tests {
    use super::api::ejecutar_demo;
    // Acceso al módulo padre para verificar tipos internos
    use super::interna::Datos;

    pub fn run_tests() {
        ejecutar_demo();
        let _d = Datos;
        println!("Tests completados");
    }
}

fn main() {
    api::ejecutar_demo();
    tests::run_tests();
}

Explicación del Código

  • pub use crate::interna::Datos;: Dentro del módulo api, estamos reexportando el tipo Datos. Esto permite que cualquier usuario de este crate acceda a api::Datos directamente, ocultando la existencia del módulo interna.
  • use crate::interna::Config;: Importación estándar utilizando una ruta absoluta desde la raíz del crate (crate).
  • use crate::externa::Herramienta as HerramientaExterna;: Aquí aplicamos un alias. Como el módulo interna::utilidades también tiene una Herramienta, renombramos la de externa para evitar que el compilador se confunda.
  • use crate::interna::utilidades::Herramienta as HerramientaInterna;: Similar al caso anterior, creamos un alias para la Herramienta interna para permitir su coexistencia con HerramientaExterna en el mismo ámbito de api.
  • use super::api::ejecutar_demo;: En el módulo tests, utilizamos la palabra clave super para subir un nivel en la jerarquía y acceder al módulo api que reside en el mismo nivel.
  • use super::interna::Datos;: Acceso directo al módulo interna mediante super, permitiendo que el módulo de pruebas valide la estructura interna del código.
  • api::ejecutar_demo();: Llamada desde main utilizando la ruta pública definida por la reexportación y la organización de módulos.

76