Moduli in Rust
I moduli in Rust organizzano il codice in namespace gerarchici, controllando la visibilità e la struttura del progetto.
Definire un Modulo
mod matematica {
pub fn somma(a: i32, b: i32) -> i32 {
a + b
}
fn helper_privato() -> i32 {
42
}
}
fn main() {
let risultato = matematica::somma(2, 3);
println!("{}", risultato); // 5
// matematica::helper_privato(); // ERRORE: funzione privata
}
Visibilità con pub
Per default tutto è privato. Usa pub per rendere gli elementi accessibili:
mod libreria {
pub struct Utente {
pub nome: String, // Campo pubblico
email: String, // Campo privato
}
impl Utente {
pub fn new(nome: String, email: String) -> Self {
Utente { nome, email }
}
pub fn email(&self) -> &str {
&self.email
}
}
}
Moduli Annidati
mod rete {
pub mod http {
pub fn get(url: &str) -> String {
format!("GET {}", url)
}
}
pub mod tcp {
pub fn connetti(host: &str, porta: u16) {
println!("Connesso a {}:{}", host, porta);
}
}
}
fn main() {
rete::http::get("https://example.com");
rete::tcp::connetti("localhost", 8080);
}
use per Abbreviare i Percorsi
use rete::http;
use rete::tcp::connetti;
fn main() {
http::get("https://example.com");
connetti("localhost", 8080);
}
// Importazioni multiple
use std::collections::{HashMap, HashSet, BTreeMap};
// Rinominare con as
use std::io::Result as IoResult;
Re-esportare con pub use
mod interno {
pub fn funzione_utile() {}
}
pub use interno::funzione_utile; // Rende accessibile al livello superiore
Moduli in File Separati
Struttura classica
src/
├── main.rs
├── matematica.rs // mod matematica
└── rete/
├── mod.rs // mod rete
├── http.rs // mod rete::http
└── tcp.rs // mod rete::tcp
Struttura moderna (Rust 2018+)
src/
├── main.rs
├── matematica.rs // mod matematica
└── rete/
├── mod.rs // mod rete (oppure rete.rs nella directory padre)
├── http.rs
└── tcp.rs
In main.rs:
mod matematica; // Carica da matematica.rs
mod rete; // Carica da rete/mod.rs
In rete/mod.rs:
pub mod http; // Carica da rete/http.rs
pub mod tcp; // Carica da rete/tcp.rs
self e super
mod padre {
pub fn saluta() {
println!("Ciao dal padre");
}
pub mod figlio {
pub fn chiama_padre() {
super::saluta(); // Accede al modulo padre
}
pub fn chiama_se_stesso() {
self::altra_funzione(); // Accede al modulo corrente
}
fn altra_funzione() {}
}
}
Conclusione
I moduli sono fondamentali per organizzare il codice Rust in modo scalabile. Usa pub con parsimonia per esporre solo l’API necessaria, use per semplificare i percorsi e pub use per creare API pubbliche pulite. La struttura a file rispecchia la gerarchia dei moduli, rendendo la navigazione del progetto intuitiva.