Sintassi di base
Un semplice programma
Abbiamo già incontrato il primo programma che stampa una stringa in output, ma adesso prendiamo in considerazione questo programma che chiede da riga di comando un nome e stampa in output un saluto.
// questo è un commento /* Questo è un commento multilinea */ use std::io; fn main() { println!("Inserisci il tuo nome"); let mut nome = String::new(); io::stdin() .read_line(&mut nome) .expect("Errore nella lettura da stdin"); println!("Ciao {nome}"); }
Vediamo ora nel dettaglio i componenti di questo programma:
#![allow(unused)] fn main() { // questo è un commento /* Questo è un commento multilinea */ }
In Rust si possono scrivere dei commenti con una sintassi simile a quella di c++ o Java.
#![allow(unused)] fn main() { use std::io; }
Come prima cosa importiamo il modulo io dalla libreria standard di Rust std. La documentazione completa del modulo si trova a questo link.
Questo ci serve per leggere una stringa da standard input.
fn main() { println!("Inserisci il tuo nome"); }
Definiamo quindi la funzione main, che è la prima a essere chiamata all'esecuzione del nostro programma. La funzione main non prende argomenti in input, al contrario di altri linguaggi di programmazione come C o Java.
Variabili
fn main() { let mut nome = String::new(); }
Tramite il costrutto let definiamo una variabile. Le variabili sono immutabili per default, ma possiamo creare una variabile mutabile inserendo anche la keyword mut.
Infatti, se proviamo a modificare una variabile immutabile
fn main() { let a = 3; a = 4; }
il compilatore Rust restituisce un errore
error[E0384]: cannot assign twice to immutable variable `a`
--> src/main.rs:3:5
|
2 | let a = 3;
| -
| |
| first assignment to `a`
| help: consider making this binding mutable: `mut a`
3 | a = 4;
| ^^^^^ cannot assign twice to immutable variable
For more information about this error, try `rustc --explain E0384`.
L'errore è dovuto al fatto che non possiamo assegnare due volte a una variabile immutabile.
Il compilatore ci suggerisce anche un possibile fix, facendo diventare la variabile a mutabile.
Cambiando il codice come segue l'errore viene risolto e il programma compila con successo.
fn main() { let mut a = 3; a = 4; }
Ritornando al programma iniziale
fn main() { let mut nome = String::new(); }
Stiamo assegnando alla variabile mutabile nome un oggetto di tipo String, ovvero una stringa ridimensionabile e codificata tramite UTF-8, che ci mette a disposizione la libreria standard. In particolare stiamo invocando il metodo associato new del tipo String, che ci permette di creare una nuova stringa.
Input/output
Passiamo adesso alle righe successive
io::stdin()
.read_line(&mut nome)
.expect("Errore nella lettura da stdin");
La funzione stdin importata dal modulo io restituisce un handle allo standard input, che è un oggetto di tipo std::io::Stdin.
Su questo oggetto viene invocato il metodo read_line, che legge una riga da standard input e la scrive all'interno della variabile nome.
La stringa nome viene passata alla funzione read_line come &mut, il che vuol dire che la stiamo passando come una reference mutabile, senza quindi la necessità di copiare l'oggetto.
Vedremo nei prossimi capitoli il meccanismo del borrowing, e come questo ci permette di gestire reference in maniera semplice e sicura.
La funzione read_line restituisce un oggetto di tipo Result, che indica il risultato di una computazione che potrebbe potenzialmente fallire.
Infatti, il valore di un oggetto Result può essere Ok oppure Err, come possiamo vedere dalla sua definizione
#![allow(unused)] fn main() { use std::io::Error; enum Result<T> { Ok(T), Err(Error), } }
Vedremo le enumerazioni in un prossimo capitolo. La funzione expect semplicemente lancia una eccezione se il risultato è un errore.
Rust rende estremamente semplice la gestione degli errori e, sebbene esista un meccanismo di eccezioni, la gestione esplicita degli errori è preferibile, in quanto garantisce che il programma non terminerà improvvisamente.
fn main() { let nome = "Test"; println!("Ciao {nome}"); }
Alla fine, stampiamo la stringa Ciao seguita dal nome. La funzione println! è in realtà una macro (tipicamente i nomi delle macro terminano con un !), che permette di specificare una formattazione per la stringa, e in questo caso d'inserire il valore di variabili da stampare.