SE VUOI PRENDERE LA CERTIFICAZIONE PER QUESTO CORSO CLICCA QUI
Moduli: Organizzare il Codice in Moduli per il Controllo di Scope e Privacy
In questa sezione, parleremo dei moduli e di altre parti del sistema di moduli, in particolare dei percorsi che ti permettono di nominare gli elementi; della parola chiave use che porta un percorso nello scope; e della parola chiave pub per rendere gli elementi pubblici. Discuteremo anche della parola chiave as, dei pacchetti esterni e dell’operatore di glob.
Per iniziare, partiremo da un elenco di regole per un facile riferimento quando organizzi il tuo codice in futuro. Successivamente, spiegheremo ogni regola nel dettaglio.
Scheda degli Appunti sui Moduli
Qui forniamo un rapido riferimento su come funzionano i moduli, i percorsi, la parola chiave use e la parola chiave pub nel compilatore, e come la maggior parte degli sviluppatori organizza il proprio codice. Per tutto questo capitolo esamineremo esempi di ciascuna di queste regole, ma questo è un ottimo punto di riferimento per ricordare come funzionano i moduli.
- Partire dalla radice del crate: Quando si compila un crate, il compilatore prima cerca nel file radice del crate (di solito src/lib.rs per un crate libreria o src/main.rs per un crate binario) il codice da compilare.
- Dichiarare i moduli: Nel file radice del crate, puoi dichiarare nuovi moduli; ad esempio, puoi dichiarare un modulo “giardino” con
mod garden;
. Il compilatore cercherà il codice del modulo in questi posti:- Inline, all’interno di parentesi graffe che sostituiscono il punto e virgola seguente
mod garden
- Nel file src/garden.rs
- Nel file src/garden/mod.rs
- Inline, all’interno di parentesi graffe che sostituiscono il punto e virgola seguente
- Dichiarare sottomoduli: In qualsiasi file diverso dal file radice del crate, puoi dichiarare sottomoduli. Ad esempio, potresti dichiarare
mod vegetables;
in src/garden.rs. Il compilatore cercherà il codice del sottomodulo all’interno della directory denominata come il modulo genitore in questi posti:- Inline, subito dopo
mod vegetables
, all’interno di parentesi graffe invece del punto e virgola - Nel file src/garden/vegetables.rs
- Nel file src/garden/vegetables/mod.rs
- Inline, subito dopo
- Percorsi al codice nei moduli: Una volta che un modulo fa parte del tuo crate, puoi fare riferimento al codice in quel modulo da qualsiasi altra parte dello stesso crate, purché le regole sulla privacy lo permettano, usando il percorso al codice. Ad esempio, un tipo Asparago nel modulo verdure del giardino sarebbe trovato a
crate::garden::vegetables::Asparago
. - Privato vs pubblico: Il codice all’interno di un modulo è privato dai suoi moduli genitori per impostazione predefinita. Per rendere un modulo pubblico, dichiaralo con
pub mod
invece dimod
. Per rendere gli elementi all’interno di un modulo pubblico, usapub
prima delle loro dichiarazioni. - La parola chiave use: All’interno di uno scope, la parola chiave
use
crea scorciatoie agli elementi per ridurre la ripetizione di percorsi lunghi. In uno scope che può fare riferimento acrate::garden::vegetables::Asparago
, puoi creare una scorciatoia conuse crate::garden::vegetables::Asparago;
e da quel momento in poi devi solo scrivereAsparago
per utilizzare quel tipo nello scope.
Qui creiamo un crate binario chiamato backyard che illustra queste regole. La directory del crate, anch’essa chiamata backyard, contiene questi file e directory:
css
backyard
├── Cargo.lock
├── Cargo.toml
└── src
├── garden
│ └── vegetables.rs
├── garden.rs
└── main.rs
Il file radice del crate in questo caso è src/main.rs, e contiene:
Nome File: src/main.rs
rust
use crate::garden::vegetables::Asparagus;
pub mod garden;
fn main() {
let plant = Asparagus {};
println!("Sto coltivando {:?}!", plant);
}
La linea pub mod garden;
dice al compilatore di includere il codice che trova in src/garden.rs, che è:
Nome File: src/garden.rs
rust
pub mod vegetables;
Qui, pub mod vegetables;
significa che viene incluso anche il codice in src/garden/vegetables.rs. Quel codice è:
rust
#[derive(Debug)]
pub struct Asparagus {}
Ora entriamo nei dettagli di queste regole e le dimostriamo in azione!
Raggruppamento del Codice Relativo nei Moduli
I moduli ci consentono di organizzare il codice all’interno di un crate per una migliore leggibilità e una facile riutilizzabilità. I moduli ci permettono anche di controllare la privacy degli elementi, perché il codice all’interno di un modulo è privato per impostazione predefinita. Gli elementi privati sono dettagli di implementazione interni non disponibili per l’uso esterno. Possiamo scegliere di rendere pubblici i moduli e gli elementi al loro interno, esponendoli per consentire al codice esterno di utilizzarli e dipendere da essi.
Come esempio, scriviamo un crate libreria che fornisca la funzionalità di un ristorante. Definiremo le firme delle funzioni ma lasceremo i loro corpi vuoti per concentrarci sull’organizzazione del codice, piuttosto che sull’implementazione di un ristorante.
Nell’industria della ristorazione, alcune parti di un ristorante sono denominate fronte casa e altre retro casa. Il fronte casa è dove sono i clienti; questo comprende dove gli ospiti sistemano i clienti, i camerieri prendono gli ordini e il pagamento, e i baristi preparano le bevande. La retro casa è dove gli chef e i cuochi lavorano in cucina, i lavapiatti puliscono e i manager svolgono il lavoro amministrativo.
Per strutturare il nostro crate in questo modo, possiamo organizzare le sue funzioni in moduli nidificati. Crea una nuova libreria chiamata ristorante eseguendo cargo new restaurant –lib; quindi inserisci il codice nel file src/lib.rs per definire alcuni moduli e firme di funzioni. Ecco la sezione del fronte casa:
rust
mod front_of_house {
mod hosting {
fn add_to_waitlist() {} fn seat_at_table() {}
} mod serving {
fn take_order() {} fn serve_order() {}
fn take_payment() {}
}
}
Definiamo un modulo con la parola chiave mod
seguita dal nome del modulo (in questo caso, front_of_house). Il corpo del modulo viene quindi inserito tra parentesi graffe. All’interno dei moduli, possiamo inserire altri moduli, come in questo caso con i moduli hosting e serving. I moduli possono anche contenere definizioni di altri elementi, come struct, enum, costanti, trait e, come nell’esempio sopra, funzioni.
Utilizzando i moduli, possiamo raggruppare le definizioni correlate insieme e indicare perché sono correlate. I programmatori che utilizzano questo codice possono navigare nel codice in base ai gruppi anziché dover leggere tutte le definizioni, rendendo più facile trovare le definizioni rilevanti per loro. I programmatori che aggiungono nuove funzionalità a questo codice saprebbero dove posizionare il codice per mantenere il programma organizzato.
In precedenza, abbiamo menzionato che src/main.rs e src/lib.rs sono chiamati radici del crate. Il motivo del loro nome è che i contenuti di uno qualsiasi di questi due file formano un modulo denominato crate alla radice della struttura dei moduli del crate, noto come albero dei moduli.
L’elenco 7-2 mostra l’albero dei moduli per la struttura nell’elenco 7-1.
markdown
crate
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment
Questo albero mostra come alcuni dei moduli siano nidificati l’uno all’interno dell’altro; ad esempio, hosting è nidificato all’interno di front_of_house. L’albero mostra anche che alcuni moduli sono fratelli tra loro, il che significa che sono definiti nello stesso modulo; hosting e serving sono fratelli definiti all’interno di front_of_house. Se il modulo A è contenuto nel modulo B, diciamo che il modulo A è il figlio del modulo B e che il modulo B è il genitore del modulo A. Nota che l’intero albero dei moduli ha come radice il modulo implicito denominato crate.
L’albero dei moduli potrebbe ricordarti l’albero delle directory del filesystem sul tuo computer; questa è una comparazione molto appropriata! Proprio come le directory in un filesystem, usi i moduli per organizzare il tuo codice. E proprio come i file in una directory, abbiamo bisogno di un modo per trovare i nostri moduli.