Rust Admin

Sistema de Módulos em Rust: mod, pub e use na Prática Já leu

Fundamentos do Sistema de Módulos em Rust O sistema de módulos em Rust é o alicerce da organização de código profissional. Ao contrário de outras linguagens que usam convenções de diretórios, Rust oferece controle explícito sobre visibilidade e importação através de palavras-chave dedicadas. Entender , e é essencial para estruturar projetos escaláveis e manuteníveis. Um módulo é um namespace que agrupa código relacionado. Pode ser definido inline em um arquivo ou em estruturas de diretório. A palavra-chave declara um módulo; controla sua visibilidade; traz itens para o escopo atual. Juntos, esses três conceitos formam um sistema robusto de encapsulamento. Declarando e Organizando Módulos com Módulos Inline Módulos podem ser declarados diretamente no arquivo usando blocos . Essa abordagem funciona bem para projetos pequenos ou quando o código está intimamente relacionado. Módulos em Arquivos Separados Para projetos maiores, organize módulos em arquivos. Rust busca automaticamente quando você declara . Em : Em : Para submódulos, crie um diretório com que declare

Fundamentos do Sistema de Módulos em Rust

O sistema de módulos em Rust é o alicerce da organização de código profissional. Ao contrário de outras linguagens que usam convenções de diretórios, Rust oferece controle explícito sobre visibilidade e importação através de palavras-chave dedicadas. Entender mod, pub e use é essencial para estruturar projetos escaláveis e manuteníveis.

Um módulo é um namespace que agrupa código relacionado. Pode ser definido inline em um arquivo ou em estruturas de diretório. A palavra-chave mod declara um módulo; pub controla sua visibilidade; use traz itens para o escopo atual. Juntos, esses três conceitos formam um sistema robusto de encapsulamento.

Declarando e Organizando Módulos com mod

Módulos Inline

Módulos podem ser declarados diretamente no arquivo usando blocos mod {}. Essa abordagem funciona bem para projetos pequenos ou quando o código está intimamente relacionado.

// src/main.rs
mod calculos {
    pub fn somar(a: i32, b: i32) -> i32 {
        a + b
    }

    fn subtrair(a: i32, b: i32) -> i32 {
        a - b
    }
}

fn main() {
    let resultado = calculos::somar(5, 3);
    println!("Resultado: {}", resultado);
    // calculos::subtrair(5, 3) causaria erro — função privada
}

Módulos em Arquivos Separados

Para projetos maiores, organize módulos em arquivos. Rust busca automaticamente nomemodulo.rs quando você declara mod nomemodulo.

src/
├── main.rs
├── utils.rs
└── operacoes/
    ├── mod.rs
    ├── aritmetica.rs
    └── logica.rs

Em src/main.rs:

mod utils;
mod operacoes;

fn main() {
    let resultado = utils::formatar("Teste");
    println!("{}", resultado);
}

Em src/utils.rs:

pub fn formatar(texto: &str) -> String {
    format!("Formatado: {}", texto)
}

Para submódulos, crie um diretório com mod.rs que declare os submódulos:

// src/operacoes/mod.rs
pub mod aritmetica;
pub mod logica;
// src/operacoes/aritmetica.rs
pub fn multiplicar(a: i32, b: i32) -> i32 {
    a * b
}

Controlando Visibilidade com pub

A visibilidade em Rust segue um princípio: tudo é privado por padrão. Você deve explicitamente tornar públicos os itens que deseja exportar. Isso evita exposição acidental e força um design consciente da API.

// src/biblioteca.rs

// Privado — não acessível fora deste módulo
struct Interno {
    valor: i32,
}

// Público — acessível em qualquer lugar
pub struct Calculadora {
    nome: String,
}

impl Calculadora {
    // Privado — apenas para uso interno
    fn validar(&self) -> bool {
        true
    }

    // Público — faz parte da API pública
    pub fn calcular(&self, x: i32) -> i32 {
        if self.validar() {
            x * 2
        } else {
            0
        }
    }
}

pub fn processar(entrada: &str) -> String {
    format!("Processado: {}", entrada)
}

Você também pode usar pub(crate) para tornar algo público apenas dentro do crate, ou pub(in caminho) para controle mais fino:

pub(crate) fn funcao_interna() {
    // Visível em todo o crate, mas não externamente
}

pub(in super) fn outra_funcao() {
    // Visível apenas no módulo pai
}

Importando com use

A palavra-chave use traz itens de módulos para o escopo atual, evitando repetição de caminhos completos. Isso melhora a legibilidade significativamente em projetos reais.

Importações Simples e Nesting

use std::collections::HashMap;
use std::fs::File;
use std::io::Read;

// Equivalente a:
use std::{
    collections::HashMap,
    fs::File,
    io::Read,
};

fn exemplo() {
    let mut mapa: HashMap<String, i32> = HashMap::new();
    mapa.insert("chave".to_string(), 42);
}

Importações Seletivas

Use * para importar todos os itens públicos de um módulo (com moderação):

use std::collections::*;

fn listar() {
    let _mapa: HashMap<String, i32> = HashMap::new();
    let _vetor: Vec<String> = Vec::new();
}

Renomeando Imports

Quando há conflitos de nomes ou para melhorar clareza:

use std::fs::File as ArquivoRust;
use std::io::Result as IoResult;

fn abrir() -> IoResult<()> {
    let _arquivo = ArquivoRust::open("teste.txt")?;
    Ok(())
}

Importações em Projetos Reais

// src/main.rs
mod database;
mod api;

use database::conectar;
use api::servidor::{iniciar, Configuracao};

fn main() {
    let config = Configuracao::padrao();
    let _conn = conectar("localhost");
    iniciar(config);
}

Conclusão

Dominar o sistema de módulos em Rust é fundamental para desenvolvimento profissional. Primeiro, use mod para organizar código em namespaces lógicos — prefira arquivos separados em projetos maiores. Segundo, aplique pub conscientemente: exponha apenas o necessário e crie APIs claras e coesas. Terceiro, use use para tornar código legível, trazendo apenas os itens necessários para o escopo atual. Esses três conceitos juntos criam uma base sólida para escalabilidade e manutenção de código.

Referências


Artigos relacionados