Desafio Rust

Módulos aninhados e controle de visibilidade

Enunciado

Crie um crate binário com a seguinte estrutura de módulos:

  • src/main.rs declara mod util; e mod app;.
  • src/util.rs contém um submódulo matematica com uma função pub fn dobro(x: i32) -> i32 e uma função pub(crate) fn triplo(x: i32) -> i32. O módulo matematica deve ser público.
  • src/app.rs contém uma função pub fn executar() que usa crate::util::matematica::dobro e crate::util::matematica::triplo para calcular e imprimir o dobro e o triplo de 5.

No main, chame app::executar(). A função triplo deve ser acessível apenas dentro do crate (use pub(crate)).

Requisitos

  • util.rs deve ter pub mod matematica com pub fn dobro e pub(crate) fn triplo.
  • app.rs deve ter pub fn executar() que chama as funções de util::matematica.
  • O main.rs deve declarar os módulos e chamar app::executar().
  • A saída deve mostrar o dobro e o triplo de 5.

Código inicial

// src/main.rs
// TODO: declarar módulos e chamar app::executar()

// src/util.rs
// TODO: criar submódulo matematica com dobro e triplo

// src/app.rs
// TODO: criar função executar

Saída esperada

Dobro: 10
Triplo: 15
Ver dica

Use pub(crate) para triplo e pub para dobro. Em app.rs, importe com use crate::util::matematica::{dobro, triplo};.

Mostrar solução
// src/main.rs
mod util;
mod app;

fn main() {
    app::executar();
}
// src/util.rs
pub mod matematica {
    // Visível fora do crate
    pub fn dobro(x: i32) -> i32 {
        x * 2
    }

    // Visível apenas dentro do crate atual
    pub(crate) fn triplo(x: i32) -> i32 {
        x * 3
    }
}
// src/app.rs
use crate::util::matematica::{dobro, triplo};

pub fn executar() {
    let x = 5;
    println!("Dobro: {}", dobro(x));
    println!("Triplo: {}", triplo(x));
}

Passo a passo

  1. Em main.rs, declaramos mod util; e mod app;. Isso carrega os arquivos src/util.rs e src/app.rs como módulos.
  2. No main, chamamos app::executar(). Como executar é pub, ela é acessível a partir da raiz.
  3. Em util.rs, criamos pub mod matematica, um submódulo público. Dentro dele, pub fn dobro é visível em qualquer lugar, e pub(crate) fn triplo é visível apenas dentro do crate.
  4. Em app.rs, usamos use crate::util::matematica::{dobro, triplo}; para importar as funções. O crate:: indica a raiz do crate.
  5. A função executar chama dobro(5) e triplo(5) e imprime os resultados.
  6. A saída mostra os valores calculados.

Por que funciona

A visibilidade pub(crate) restringe o acesso ao crate atual, impedindo que outros crates usem triplo. Já pub permite exportar dobro para fora. O caminho crate::util::matematica::dobro navega da raiz até o item. O use traz os nomes para o escopo local, simplificando as chamadas. A estrutura de arquivos reflete a hierarquia de módulos: util.rs contém o módulo matematica embutido.

Erros comuns

  • Esquecer pub no módulo matematica: mod matematica sem pub torna o módulo privado, e app.rs não consegue acessá-lo.
  • Usar pub fn triplo em vez de pub(crate): isso exporia a função para fora do crate, contrariando o requisito.
  • Tentar acessar util::matematica::triplo de outro crate: o compilador acusaria que a função é privada.
  • Não usar crate:: no use dentro de app.rs: use util::matematica::... pode falhar porque util não está no escopo atual; o correto é crate::util::....

Outra forma de resolver

Colocar o módulo matematica em um arquivo separado src/util/matematica.rs e em src/util.rs declarar pub mod matematica;. Isso é preferível quando o submódulo cresce. Exemplo:

// src/util.rs
pub mod matematica;
// src/util/matematica.rs
pub fn dobro(x: i32) -> i32 { x * 2 }
pub(crate) fn triplo(x: i32) -> i32 { x * 3 }

Saída esperada

Dobro: 10
Triplo: 15