Pacchetti e Crate
Le prime parti del sistema dei moduli che tratteremo sono i pacchetti e i crate.
Un crate è la quantità minima di codice che il compilatore Rust considera in
un dato momento. Anche se esegui rustc
invece di cargo
e passi un singolo
file di codice sorgente (come abbiamo fatto all’inizio in “Programma Rust
Basilare” nel Capitolo 1), il compilatore considera quel
file come un crate. I crate possono contenere moduli, e i moduli possono
essere definiti in altri file che vengono compilati con il crate, come vedremo
nelle sezioni successive.
Un crate può presentarsi in una delle due forme: un crate binario o un
crate libreria. I crate binari sono programmi che puoi compilare in un
eseguibile che puoi eseguire, come un programma da riga di comando o un server.
Ognuno deve avere una funzione chiamata main
che definisce cosa succede quando
l’eseguibile viene eseguito. Tutti i crate che abbiamo creato finora sono
stati crate binari.
I crate libreria non hanno una funzione main
, e non si compilano in un
eseguibile. Invece, definiscono funzionalità destinate a essere condivise con
progetti multipli. Ad esempio, il crate rand
che abbiamo usato nel Capitolo
2 fornisce funzionalità che generano numeri casuali. La
maggior parte delle volte, quando i Rustacean dicono “crate”, intendono
crate libreria, e usano “crate” in modo intercambiabile con il concetto
generale di programmazione di una “libreria”.
La radice del crate (crate root) è un file sorgente da cui il compilatore Rust inizia e costituisce il modulo radice del tuo crate (spiegheremo i moduli in dettaglio nel capitolo “Controllare Scope e Privacy con i Moduli”).
Un pacchetto (package) è un insieme di uno o più crate che fornisce un insieme di funzionalità. Un pacchetto contiene un file Cargo.toml che descrive come costruire quei crate. Cargo è anch’esso in realtà un pacchetto che contiene il crate binario per lo strumento da riga di comando che hai usato per costruire il tuo codice finora. Il pacchetto Cargo contiene anche un crate libreria di cui il crate binario ha bisogno. Altri progetti possono dipendere dal crate libreria Cargo per utilizzare la stessa logica che utilizza lo strumento da riga di comando Cargo.
Un pacchetto può contenere quanti più crate binari desideri, ma al massimo solo un crate libreria. Un pacchetto deve contenere almeno un crate, sia esso un crate libreria o binario.
Esploriamo cosa succede quando creiamo un pacchetto. Cominciamo con il comando
cargo new mio-progetto
:
$ cargo new mio-progetto
Created binary (application) `mio-progetto` package
$ ls mio-progetto
Cargo.toml
src
$ ls mio-progetto/src
main.rs
Dopo aver eseguito cargo new mio-progetto
, usiamo ls
per vedere cosa crea
Cargo. Nella cartella mio-progetto
, c’è un file Cargo.toml, che definisce un
pacchetto. C’è anche una cartella src che contiene main.rs. Apri
Cargo.toml nel tuo editor di testo e nota che non c’è menzione di
src/main.rs. Cargo segue una convenzione secondo cui src/main.rs è la radice
del crate di un crate binario con lo stesso nome del pacchetto. Allo
stesso modo, Cargo sa che se la cartella del pacchetto contiene src/lib.rs, il
pacchetto contiene un crate libreria con lo stesso nome del pacchetto, e
src/lib.rs è la sua radice del crate. Cargo passa i file di radice del
crate a rustc
per costruire la libreria o il binario.
Qui, abbiamo un pacchetto che contiene solo src/main.rs, il che significa che
contiene solo un crate binario chiamato mio-progetto
. Se un pacchetto
contiene src/main.rs e src/lib.rs, avrà due crate: uno binario e uno
libreria, entrambi con lo stesso nome del pacchetto. Un pacchetto può avere più
crate binari posizionando file nella cartella src/bin: ogni file sarà un
crate binario separato.