Panoramica del linguaggio Rust
Edizione Rust 2024 — linguaggio di sistema | sicurezza della memoria senza GC | concorrenza senza paura | astrazioni a costo zero
Paradigma
Multi-paradigma: imperativo, funzionale, orientato agli oggetti (tratti), orientato ai dati. Tipizzazione statica con inferenza completa, sistema di tipi nominali, tipi di dati algebrici. Compilazione tramite LLVM. Il controllo del prestito impone la sicurezza della memoria in fase di compilazione.
Tipi
| Categoria |
Tipi |
| Firmato int |
i8 i16 i32 i64 i128 isize |
| Intero non firmato |
u8 u16 u32 u64 u128 usize |
| Galleggiante |
f32 f64 |
| Bool |
bool |
| Car |
char (scalare Unicode a 4 byte) |
| Unità |
() |
| Fetta |
&[T] &mut [T] |
| Matrice |
[T; N] |
| Tupla |
(T1, T2, ...) |
| Riferimento |
&T &mut T |
| Puntatore grezzo |
*const T *mut T |
| Opzione |
Option<T> |
| Risultato |
Result<T, E> |
| Stringa |
String &str |
| Scatola |
Box<T> (allocazione heap) |
| Vec |
Vec<T> (array dinamico) |
| Puntatori intelligenti |
Rc<T> Arc<T> Cell<T> RefCell<T> |
| Puntatore di funzione |
fn(T) -> U |
| Chiusura |
|args| body (tipo unico per chiusura) |
| Oggetto tratto |
dyn Trait |
| Mai |
! (divergente) |
Dichiarazioni
| Costruisci |
Sintassi |
Note |
| Funzione |
fn name(params) -> Ret { body } |
|
| Metodo |
fn name(&self, params) -> Ret { body } |
Dentro impl blocco |
| Variabile |
let x = expr; |
Immutabile per impostazione predefinita |
| Mutevole |
let mut x = expr; |
|
| Destrutturare |
let (a, b) = tuple; |
|
| Costante |
const NAME: T = expr; |
In fase di compilazione, in linea |
| Statico |
static NAME: T = expr; |
Indirizzo fisso |
| Struttura |
struct Name { field: T } |
Campi nominati |
| Struttura della tupla |
struct Name(T1, T2); |
|
| Struttura dell'unità |
struct Name; |
|
| Enum |
enum Name { Variant, Var(T) } |
ADT |
| Unione |
union Name { f1: T1, f2: T2 } |
Non sicuro |
| Caratteristica |
trait Name { fn method(&self); } |
|
| Imp |
impl Type { fn ... } |
|
| Tratto implicito |
impl Trait for Type { fn ... } |
|
| Digita l'alias |
type Alias = T; |
|
| Importa |
use crate::module::Item; |
|
| Macro |
macro_rules! name { ... } |
|
| Modulo |
mod name; |
|
| Cassa |
extern crate name; (edizione 2015) |
|
Proprietà e prestiti
Each value has exactly one owner.
Ownership can be moved (assignment, function call).
References (&T) borrow without taking ownership.
Mutable references (&mut T) are exclusive — only one at a time.
References must never outlive their referent (lifetimes).
Regole di prestito
- Uno
&mut T XOR molti &T in qualsiasi momento
- I riferimenti sono sempre validi (nessun puntatore penzolante)
- Durata elisa se non ambigua (
'a, 'static)
Flusso di controllo
| Costruisci |
Sintassi |
Note |
| Se |
if cond { ... } else { ... } |
Espressione |
| Se-let |
if let Pattern(expr) = val { ... } |
Destrutturazione+abbinamento |
| Mentre |
while cond { ... } |
|
| Mentre-let |
while let Some(v) = opt { ... } |
|
| Per |
for x in iter { ... } |
Utilizza IntoIterator |
| Ciclo |
loop { ... } |
Infinito (può break con valore) |
| Partita |
match expr { Pattern => body, ... } |
Esauriente |
| Pausa |
break; / break val; |
|
| Continua |
continue; |
|
| Ritorno |
return expr; |
Ritorna anche l'espressione alla fine del blocco |
Modelli di corrispondenza
Pattern := Literal | Identifier | _ | ref | mut | @ binding
| Tuple(x, y) | Struct { field } | Enum::Variant(x)
| x | y (OR) | x @ y (bind) | .. (rest)
| ... (inclusive range) | ..= (inclusive range)
Guards := Pattern if condition => body
Operatori
| Categoria |
Operatori |
| Aritmetica |
+ - * / % |
| Confronto |
== != < > <= >= |
| Logico |
&& || ! |
| Bit per bit |
& | ^ ! << >> |
| Composto |
+= -= *= /= %= &= |= ^= <<= >>= |
| Gamma |
.. ..= .. (semiaperto) ..= (incluso) |
| Deref |
*expr |
| Riferimento |
&expr &mut expr |
| Punto interrogativo |
expr? (reso anticipato su Err/None) |
| Turbopesce |
::<T> (annotazione del tipo sui farmaci generici) |
| Attributo |
#[attr] #![attr] |
Sistema dei tratti
Tratti standard (selezionati)
| Caratteristica |
Scopo |
Clone |
Copia approfondita (x.clone()) |
Copy |
Copia bit a bit (implicita, opt-in) |
Drop |
Distruttore |
Default |
Valore predefinito |
Debug |
Formato con {:?} |
Display |
Formato rivolto all'utente {} |
Eq / PartialEq |
Confronto sull'uguaglianza |
Ord / PartialOrd |
Confronto degli ordini |
Hash |
Hashing |
Iterator |
fn next(&mut self) -> Option<Item> |
IntoIterator |
Converti in iteratore |
From / Into |
Conversione del tipo |
TryFrom / TryInto |
Conversione fallibile |
Deref |
Dereferenza implicita |
AsRef / AsMut |
Conversione di riferimento |
Borrow / BorrowMut |
Prendi in prestito come un altro tipo |
Send / Sync |
Indicatori di sicurezza del filo |
Sized |
Dimensioni note al momento della compilazione |
Fn FnMut FnOnce |
Tratti di chiusura |
impl Trait / dyn Trait
impl Trait — tipo di reso opaco (invio statico)
dyn Trait — oggetto tratto (invio dinamico)
where clausole per limiti complessi: fn f<T>() where T: Clone + Debug
Generici
fn id<T: Display>(x: T) -> T { x }
struct Pair<T, U> { first: T, second: U }
enum Option<T> { Some(T), None }
impl<T: Clone> Pair<T, T> { fn duplicate(&self) -> Self { ... } }
Modello di memoria
Assegnazione
- Stack: variabili locali, array a dimensione fissa
- Mucchio:
Box<T>, Vec<T>, String, Rc<T>, Arc<T>
alloc / Layout per assegnazione manuale (in std::alloc)
Puntatori intelligenti
Box<T> — allocazione dell'heap di proprietà, unico proprietario
Rc<T> — con conteggio dei riferimenti (non thread-safe)
Arc<T> — con conteggio atomico dei riferimenti (threadsafe)
Cell<T> — mutabilità interiore per Copy tipi
RefCell<T> — controllo del prestito in fase di esecuzione
Mutex<T> / RwLock<T> — mutabilità interna thread-safe
UnsafeCell<T> — cruda mutabilità interiore
Concorrenza
| Primitivo |
Posizione |
std::thread::spawn |
Creazione del thread |
std::sync::mpsc |
Canali multiproduttore e monoconsumatore |
crossbeam::channel |
Canali multiproduttore e multiconsumatore (esterni) |
Mutex<T> RwLock<T> |
Primitive di sincronizzazione |
Arc<T> |
Conteggio dei riferimenti atomici |
std::sync::Barrier Condvar |
Coordinamento |
async/await (dalla 1.39) |
Async/await con futures |
tokio / async-std |
Runtime asincroni (esterni) |
std::sync::Once OnceLock LazyLock |
Inizializzazione una tantum |
Libreria standard (moduli selezionati)
| Modulo |
Contenuto |
std::io |
Read Write BufRead BufReader BufWriter Stdin Stdout |
std::fs |
File read write create_dir remove_file metadata |
std::net |
TcpStream TcpListener UdpSocket IpAddr |
std::collections |
Vec HashMap HashSet BTreeMap BTreeSet LinkedList VecDeque BinaryHeap |
std::path |
Path PathBuf |
std::env |
args var current_dir temp_dir |
std::process |
Command Output Child exit |
std::time |
Duration Instant SystemTime |
std::sync |
Mutex RwLock Arc Barrier Condvar Once mpsc |
std::thread |
spawn sleep park yield_now current |
std::ffi |
CString CStr OsString OsStr |
std::os |
Estensioni specifiche della piattaforma |
std::ptr |
read write null NonNull addr_of addr_of_mut |
Gestione degli errori
// Recoverable: Result<T, E>
fn div(a: i32, b: i32) -> Result<i32, String> {
if b == 0 { Err("division by zero".into()) }
else { Ok(a / b) }
}
let r = div(10, 2)?; // early return on Err
// Unrecoverable: panic!
panic!("something went wrong");
// Expected/unexpected split
// Result for recoverable, panic for programmer errors
Rust non sicuro
unsafe { ... } i blocchi abilitano:
- Dereferenziazione del puntatore grezzo
- Chiamare funzioni non sicure (FFI)
- Access/modify statica mutevole
- Implementa tratti non sicuri
- Accesso al campo dell'Unione
Il controllo del prestito è ancora valido all'interno di unsafe.
Test
#[test]
fn test_addition() {
assert_eq!(2 + 2, 4);
assert!(true);
assert_ne!(1, 2);
}
Attributi di prova
#[test] #[should_panic] #[ignore] #[cfg(test)] #[bench]
| Componente |
Scopo |
rustc |
Compilatore (LLVM back-end) |
cargo |
Gestore pacchetti, sistema di compilazione |
rustup |
Gestore della catena di strumenti |
rustfmt |
Formattatore di codice |
clippy |
Linter |
rust-analyzer |
server LSP |
cargo-doc |
Generatore di documentazione |
cargo-test |
Corridore di prova |
cargo-bench |
Benchmark |
cargo-clippy |
Controlli della lanugine |
Edizioni
| Edizione |
Cambiamenti chiave |
| 2015 |
Edizione stabile iniziale |
| 2018 |
Vite non lessicali, modifiche al sistema dei moduli, impl Trait, dyn Trait |
| 2021 |
Modifiche al preludio, IntoIterator per gli array, campo edizione Cargo.toml obbligatorio |
| 2024 |
impl Trait ovunque, gen blocchi, unsafe attributi, if let catene stabili, mai tipo ! stabile |
Compilazione
rustc file.rs # compile
cargo new project # new project
cargo build # debug build
cargo build --release # release build
cargo run # build + run
cargo test # run tests
cargo doc --open # generate docs
cargo check # type-check without codegen
Obiettivi
x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu x86_64-pc-windows-msvc x86_64-apple-darwin wasm32-unknown-unknown wasm32-wasi thumbv7em-none-eabihf (oltre 100 target)
Interoperabilità C
// FFI declaration
extern "C" {
fn printf(fmt: *const u8, ...) -> i32;
}
// Linking
#[link(name = "m")]
extern "C" { fn sqrt(x: f64) -> f64; }
// ABI types
// i32 → c_int, u64 → c_ulonglong, *const T → *const c_void