Torna ai corsi
AI034 Professional

Il linguaggio di programmazione Rust

Una guida completa e introduttiva a Rust, che copre i concetti di programmazione a sistema, la sicurezza della memoria, la concorrenza e lo strumentario di Rust (Cargo, rustup). Il corso passa dalla sintassi base alla realizzazione di progetti completi come un server web multithreadato.

5.0
63.0h
763 studenti
0 mi piace
Intelligenza Artificiale
Inizia ad imparare

Panoramica del corso

📚 Riepilogo del contenuto

Una guida introduttiva completa a Rust, che copre concetti di programmazione a livello di sistema, sicurezza della memoria, concorrenza e strumenti Rust (Cargo, rustup). Il percorso va dalla sintassi di base alla creazione di progetti completi come un server web multithread.

Padroneggia l'arte della programmazione sistematica sicura, veloce e concorrente con la guida definitiva a Rust.

Autore: Steve Klabnik e Carol Nichols, con contributi dalla comunità Rust

Ringraziamenti: Contributi da parte della comunità Rust; pubblicato in formato cartaceo e ebook da No Starch Press.

🎯 Obiettivi di apprendimento

  1. Installare e gestire toolchain Rust con rustup su diverse piattaforme operative.
  2. Scrivere, compilare ed eseguire un programma Rust di base, identificando le componenti anatomiche fondamentali del codice.
  3. Usare Cargo per creare strutture di progetto standardizzate, gestire le build e produrre binari ottimizzati per il rilascio.
  4. Catturare e memorizzare l'input dell'utente, gestendo la mutabilità delle variabili e potenziali errori di I/O.
  5. Integrare dipendenze esterne tramite Cargo e gestire build riproducibili tramite Cargo.lock.
  6. Implementare la logica di gioco usando inferenza dei tipi, parsing di stringhe, cicli e l'operatore di flusso di controllo match.
  7. Distinguere tra costanti e shadowing di variabili per gestire immutabilità dei dati e ambito.
  8. Implementare correttamente tipi scalari (interi, float, booleani, caratteri) e composti (tuple, array).
  9. Distinguere tra istruzioni ed espressioni per definire funzioni con valori di ritorno specifici.
  10. Distinguere tra memoria dello stack e heap e spiegare come Rust gestisce i dati dell'heap.

🔹 Lezione 1: Avvio con Rust

Panoramica: Questa lezione offre un'introduzione completa all'ecosistema Rust, con focus sulla configurazione dell'ambiente e sul flusso di lavoro fondamentale dello sviluppatore Rust. Gli studenti passeranno dall'installazione del linguaggio tramite rustup alla scrittura di un programma "Hello, World!" manuale, fino a padroneggiare Cargo, il sistema di build ufficiale di Rust e il gestore di pacchetti, per una gestione professionale dei progetti e ottimizzazione del rilascio.

Risultati formativi:

  • Installare e gestire correttamente le toolchain Rust con rustup su diverse piattaforme operative.
  • Scrivere, compilare ed eseguire un programma Rust di base, identificando le componenti anatomiche fondamentali del codice.
  • Usare Cargo per creare strutture di progetto standardizzate, gestire le build e produrre binari ottimizzati per il rilascio.

🔹 Lezione 2: Pratica: Programmazione di un gioco dell’indovinello

Panoramica: Questa lezione guida gli sviluppatori nella costruzione di un gioco basato su CLI funzionale in Rust. Copre concetti fondamentali di programmazione a livello di sistema come il processamento dell'input utente, l'integrazione di crate esterne per la generazione di numeri casuali e l'approccio unico di Rust alla sicurezza della memoria e al gestione degli errori tramite il tipo Result e il pattern matching. Al termine, gli apprendisti avranno un'applicazione robusta che gestisce input non validi e garantisce build riproducibili.

Risultati formativi:

  • Catturare e memorizzare l'input dell'utente, gestendo la mutabilità delle variabili e potenziali errori di I/O.
  • Integrare dipendenze esterne tramite Cargo e gestire build riproducibili tramite Cargo.lock.
  • Implementare la logica del gioco usando inferenza dei tipi, parsing di stringhe, cicli e l'operatore di flusso di controllo match.

🔹 Lezione 3: Concetti di programmazione comuni

Panoramica: Questa lezione copre i blocchi fondamentali della programmazione in Rust, concentrandosi su come i dati vengono archiviati e manipolati. Esplora le sfumature del shadowing di variabili e delle costanti, la categorizzazione dei dati in tipi scalari e composti, le regole strutturali delle funzioni e la logica che governa il flusso di controllo e l'esecuzione ripetuta.

Risultati formativi:

  • Distinguere tra costanti e shadowing di variabili per gestire immutabilità dei dati e ambito.
  • Implementare correttamente tipi scalari (interi, float, booleani, caratteri) e composti (tuple, array).
  • Distinguere tra istruzioni ed espressioni per definire funzioni con valori di ritorno specifici.

🔹 Lezione 4: Comprensione dell’Ownership e della memoria

Panoramica: Questa lezione esplora l'approccio unico di Rust alla gestione della memoria attraverso il suo sistema di Ownership. Invece di affidarsi a un garbage collector o alla gestione manuale della memoria, Rust utilizza un insieme di regole verificate in fase di compilazione per garantire la sicurezza della memoria. Questo capitolo copre i meccanismi dello stack e heap, il ciclo di vita dei dati e come riferimenti e fette (slices) forniscano un accesso sicuro ed efficiente alla memoria senza trasferire l'ownership.

Risultati formativi:

  • Distinguere tra memoria dello stack e heap e spiegare come Rust gestisce i dati dell'heap.
  • Applicare le tre regole dell’Ownership per prevedere validità e ambito delle variabili.
  • Dimostrare la differenza tra operazioni Move, Clone e Copy.

🔹 Lezione 5: Struct: Gestione dei dati correlati

Panoramica: Questa lezione esplora come raggruppare dati correlati in tipi personalizzati usando struct per creare codice più significativo e organizzato. Copre la definizione e l'istanziazione di varie forme di struct (classiche, tuple, unit-like), la gestione dell'ownership dei dati all'interno di queste strutture e l'arricchimento delle struct tramite trait derivati come Debug e metodi personalizzati definiti tramite blocchi impl.

Risultati formativi:

  • Definire e istanziare struct usando campi nominati, sintassi compatta e sintassi di aggiornamento.
  • Distinguere tra struct classiche, struct tuple e struct unit-like e identificare i loro casi d'uso.
  • Implementare il trait Debug e usare il macro dbg! per ispezionare i dati delle struct.

🔹 Lezione 6: Enum e Pattern Matching

Panoramica: Questa lezione esplora come Rust utilizza le enumerazioni (enum) per definire tipi elencando le varianti possibili, offrendo un modo più flessibile per raggruppare costanti correlate e dati rispetto alle struct da sole. Copre il ruolo cruciale dell'enum Option nel eliminare gli errori di puntatore nullo e dimostra come i costrutti match e if let forniscono un potente flusso di controllo esaustivo per gestire in modo sicuro schemi di dati complessi.

Risultati formativi:

  • Definire enum con diversi tipi di dati e implementare metodi su di essi usando blocchi impl.
  • Spiegare i vantaggi di sicurezza dell'enum Option<T> rispetto ai valori null tradizionali.
  • Costruire espressioni match esaustive che si legano ai valori interni delle varianti e usare placeholder universali.

🔹 Lezione 7: Moduli, Pacchetti e Crate

Panoramica: Questa lezione esplora come Rust organizza il codice per migliorarne la leggibilità e il riutilizzo tramite il suo sistema di moduli. Copre la creazione di un albero di moduli, l'applicazione delle regole di privacy per controllare la visibilità degli elementi e l'uso di percorsi e parole chiave come use e pub per gestire l'ambito e creare API pulite.

Risultati formativi:

  • Organizzare il codice in una struttura gerarchica usando moduli e albero di moduli.
  • Riferirsi agli elementi del codice usando sia percorsi assoluti che relativi.
  • Controllare la visibilità di funzioni, moduli e campi usando la parola chiave pub e le regole di privacy.

🔹 Lezione 8: Collezioni comuni

Panoramica: Questa lezione esplora le collezioni della libreria standard di Rust, concentrandosi specificamente su Vettori, Stringhe e Mappe Hash. Queste strutture dati sono memorizzate nell'heap, consentendo di crescere o ridursi in tempo reale, e la lezione dettaglia come le regole di ownership e borrowing di Rust garantiscano sicurezza della memoria e prestazioni quando si gestiscono queste liste di valori, testo UTF-8 e associazioni chiave-valore.

Risultati formativi:

  • Implementare liste dinamiche usando Vec<T> e gestirne il ciclo di vita tramite il borrow checker.
  • Manipolare testo codificato in UTF-8 usando il tipo String, navigando le complessità della rappresentazione interna e della concatenazione.
  • Applicare HashMap<K, V> per memorizzare e aggiornare dati associati in modo efficiente usando l'API Entry e considerazioni personalizzate sull'hashing.

🔹 Lezione 9: Strategie di gestione degli errori

Panoramica: Questa lezione esplora il solido approccio di Rust alla gestione degli errori, che distingue tra errori recuperabili e irrecoverabili. Gli studenti impareranno a usare il macro panic! per errori fatali, l'enum Result per fallimenti gestibili e l'operatore ? per semplificare la propagazione degli errori. Inoltre, la lezione copre come usare il sistema dei tipi di Rust per imporre convalida dei dati e mantenere l'integrità del programma.

Risultati formativi:

  • Identificare quando usare panic! irrecoverabile invece di Result recuperabile in base ai criteri di "stato errato".
  • Utilizzare backtraces per diagnosticare l'origine degli errori irrecoverabili.
  • Implementare la propagazione degli errori usando l'operatore ? e modificare la funzione main per supportare il ritorno di errori.

🔹 Lezione 10: Generics, Traits e Lifetimes

Panoramica: Questa lezione esplora gli strumenti di Rust per l'astrazione efficace: Generics per ridurre la duplicazione di codice tra tipi, Traits per definire comportamenti condivisi (interfacce) e Lifetimes per garantire la sicurezza della memoria senza gestione manuale. Insieme, queste funzionalità permettono di scrivere codice ad alte prestazioni, riutilizzabile e verificato dal compilatore per evitare riferimenti pendenti e incompatibilità di tipo.

Risultati formativi:

  • Definire e usare parametri di tipo generici in funzioni, struct e enum per gestire più tipi di dati.
  • Implementare comportamenti condivisi usando Traits e Bounds di Trait per limitare i tipi generici.
  • Applicare annotazioni di Lifetime e regole di Elision per gestire la validità dei riferimenti e soddisfare il borrow checker.

🔹 Lezione 11: Scrittura di test automatizzati

Panoramica: Questa lezione esplora l'implementazione e l'organizzazione dei test automatizzati in Rust. Copre i requisiti strutturali di una funzione di test, l'uso di macro di asserzione per verificare la logica e le distinzioni tecniche tra test unitari e test di integrazione. Gli apprendisti comprendono anche come controllare il comportamento del runner di test di Rust per gestire il flusso di esecuzione e la visibilità.

Risultati formativi:

  • Definire la struttura e i metadati richiesti per una funzione di test Rust valida.
  • Implementare controlli di uguaglianza e verifica di stato di panic per garantire la affidabilità del codice.
  • Configurare il runner di test per esecuzione parallela o consecutiva e visibilità dell'output del programma.

🔹 Lezione 12: Progetto I/O: Strumento da riga di comando

Panoramica: Questa lezione guida gli sviluppatori nella creazione di uno strumento da riga di comando funzionale (una versione semplificata di grep) in Rust. Si concentra sul passaggio da uno script a file singolo a un binario modulare e pronto per la produzione, enfatizzando l'analisi sicura degli argomenti, l'I/O di file e la separazione delle responsabilità tra la logica della libreria e l'interfaccia da riga di comando. Gli apprendisti implementeranno una gestione degli errori robusta e svilupperanno funzionalità usando lo sviluppo guidato dai test (TDD), gestendo lo stato dell'applicazione tramite variabili d'ambiente.

Risultati formativi:

  • Catturare e trasformare gli argomenti da riga di comando in oggetti di configurazione strutturati.
  • Riformattare il codice per seguire il principio "Separazione delle Preoccupazioni" nei progetti binari.
  • Implementare la logica principale usando un ciclo TDD con annotazioni di lifetime.

🔹 Lezione 13: Funzionalità avanzate: Iteratori e Closure

Panoramica: Questa lezione esplora le funzionalità di programmazione funzionale di Rust, concentrandosi specificamente su closure e iteratori. Le closure sono funzioni anonime che possono catturare il loro ambiente, governate dai trait Fn, mentre gli iteratori offrono un modo lazy ed efficiente per elaborare sequenze di elementi. Insieme, queste funzionalità permettono codice espressivo che rispetta il principio di "astrazione a costo zero" di Rust, spesso corrispondente o superiore alle prestazioni di cicli tradizionali.

Risultati formativi:

  • Definire funzioni anonime (closure) e spiegare come catturano variabili dal loro ambiente tramite prestito o movimento.
  • Distinguere tra i tre trait Fn (Fn, FnMut e FnOnce) e capire come il compilatore inferisca i tipi delle closure.
  • Implementare il trait Iterator usando il metodo next e distinguere tra adaptor consumatori e adaptor di iteratore.

🔹 Lezione 14: Cargo avanzato e Crates.io

Panoramica: Questa lezione esplora le funzionalità avanzate del gestore di pacchetti di Rust, Cargo, e del suo ecosistema, Crates.io. Si concentra sull'ottimizzazione delle build tramite profili di rilascio, sulla creazione di documentazione professionale integrata con test e sul dominio dell'architettura di API pubbliche. Inoltre, copre il ciclo di vita di un crate – dalla pubblicazione e versioning al gestione di progetti multi-pacchetto tramite workspaces e all'estensione della funzionalità nativa di Cargo.

Risultati formativi:

  • Configurare Profili di Rilascio per bilanciare velocità di compilazione e prestazioni runtime.
  • Generare e verificare commenti di documentazione che servono sia come guide per utenti che come test automatici.
  • Progettare un'API pubblica conveniente usando rielaborazioni (pub use) per separare la struttura interna dall'uso esterno.

🔹 Lezione 15: Puntatori intelligenti

Panoramica: Questa lezione esplora i puntatori intelligenti di Rust – strutture dati che agiscono come puntatori ma portano informazioni aggiuntive e capacità. Ci concentriamo sulla gestione dell'allocazione nell'heap con Box<T>, sull'abilitazione dell'ownership condivisa con Rc<T> e sul bypass delle rigide regole di prestito tramite il modello di mutabilità interna con RefCell<T>. Inoltre, copriamo i trait Deref e Drop che sono alla base del comportamento dei puntatori intelligenti e della pulizia delle risorse.

Risultati formativi:

  • Implementare strutture dati ricorsive usando Box<T> per fornire indirezione e dimensioni di memoria note.
  • Personalizzare il comportamento del puntatore e la gestione delle risorse usando i trait Deref e Drop.
  • Gestire più proprietari e mutabilità controllata in tempo di esecuzione combinando Rc<T> e RefCell<T>.

🔹 Lezione 16: Concorrenza senza timore

Panoramica: Questa lezione esplora la filosofia della "Concorrenza senza timore" di Rust, dimostrando come il linguaggio sfrutti i suoi sistemi di ownership e tipi per trasformare la programmazione concorrente da un campo minato di runtime in una certezza di compilazione. Copriamo la creazione di thread, la comunicazione sicura tramite passaggio di messaggi, la gestione dello stato condiviso usando mutex e i tratti fondamentali che definiscono la sicurezza dei thread.

Risultati formativi:

  • Creare e gestire thread usando spawn e join, risolvendo conflitti di ownership con la parola chiave move.
  • Implementare la concorrenza basata sul passaggio di messaggi usando canali mpsc per trasferire dati in modo sicuro tra thread.
  • Gestire lo stato condiviso tra più thread usando Mutex<T> per l'esclusione reciproca e Arc<T> per il conteggio di riferimenti sicuro nei thread.

🔹 Lezione 17: Programmazione orientata agli oggetti in Rust

Panoramica: Questa lezione esplora come Rust implementa principi fondamentali della programmazione orientata agli oggetti (OOP), concentrandosi specificamente su incapsulamento e polimorfismo. Dettaglia i meccanismi degli oggetti di trait per gestire collezioni eterogenee e i compromessi tra dispatch statico e dinamico. Infine, confronta l'implementazione del classico Pattern Stato con un approccio più idiomatico di Rust che codifica stati e comportamenti direttamente nel sistema dei tipi.

Risultati formativi:

  • Implementare l'incapsulamento in Rust usando moduli e modificatori di visibilità per nascondere lo stato interno.
  • Usare oggetti di trait per ottenere polimorfismo e comprendere le implicazioni di prestazioni tra dispatch statico e dinamico.
  • Applicare il Pattern Stato per gestire comportamenti complessi degli oggetti e transizioni tra stati.

🔹 Lezione 18: Pattern e corrispondenza avanzati

Panoramica: Questa lezione esplora la profondità del sistema di corrispondenza di pattern di Rust, andando oltre bracci semplici match per esplorare estrazioni di dati sofisticate e flussi di controllo. Gli studenti padroneggeranno la distinzione tra pattern irrefutabili e refutabili, impareranno a destrutturare strutture nidificate complesse e utilizzeranno sintassi avanzate come guardie di match e binding per scrivere codice più espressivo e sicuro.

Risultati formativi:

  • Distinguere tra pattern irrefutabili e refutabili e applicarli ai costrutti Rust corretti (es. let vs. if let).
  • Destrutturare struct, enum e tuple per estrarre dati specifici in variabili locali.
  • Usare sintassi di pattern avanzate, incluse intervalli, più pattern, ignorare valori e binding @ per corrispondenze condizionali complesse.

🔹 Lezione 19: Funzionalità avanzate e Rust non sicuro

Panoramica: Questa lezione esplora le "superpoteri" di Rust che permettono agli sviluppatori di aggirare certe restrizioni del compilatore e creare astrazioni altamente flessibili. Copriamo l'uso di Rust non sicuro per manipolazioni di memoria a basso livello, tecniche avanzate di trait per relazioni di tipo complesse e le potenti capacità di metaprogrammazione di Macro Dichiarativi e Procedurali.

Risultati formativi:

  • Distinguere tra Rust sicuro e le "superpoteri" non sicuri necessari per manipolazioni di puntatori grezzi e chiamate a funzioni non sicure.
  • Implementare pattern di trait avanzati inclusi Tipi Associati, Sovrascrittura di operatori, Supertrait e il pattern Newtype.
  • Distinguerle chiamate di metodi usando la sintassi completamente qualificata e gestire tipi complessi come Tipi Dimensionati Dinamicamente (DST) e Alias di tipo.

🔹 Lezione 20: Progetto finale: Server web multithread

Panoramica: Questa lezione guida lo sviluppo di un server web ad alte prestazioni usando i primitivi di rete e concorrenza di Rust. Copre il passaggio da un listener TCP di base a un sistema multithread sofisticato che utilizza un pool di thread personalizzato. Gli studenti impareranno a gestire stream a basso livello, implementare il passaggio di messaggi basato su worker per la distribuzione dei compiti e garantire la stabilità del sistema tramite un meccanismo di arresto ordinato.

Risultati formativi:

  • Stabilire e gestire connessioni TCP: associare un server a una porta locale e gestire flussi di byte in ingresso.
  • Analizzare e rispondere a richieste HTTP: leggere dati di richiesta grezzi e costruire risposte HTTP valide con linee di stato e corpi HTML.
  • Architettare un pool di thread personalizzato: usare canali mpsc e primitive di sincronizzazione (Arc, Mutex) per distribuire compiti su un numero finito di thread.

🔹 Lezione 21: Appendici Rust: Strumenti e riferimenti

Panoramica: Questa lezione fornisce un'ampia referenza tecnica per il linguaggio Rust, concentrandosi sulla sua sintassi densa, sugli strumenti di sviluppo automatizzati e sul processo evolutivo di rilascio. Gli studenti impareranno a navigare la sintassi pesantemente simbolica di Rust, a implementare comportamenti standard tramite trait derivabili e a sfruttare gli strumenti dell'ecosistema per mantenere un'elevata qualità del codice e seguire la filosofia del linguaggio "stabilità senza stagnazione".

Risultati formativi:

  • Identificare e interpretare la sintassi: decodificare operatori, simboli legati ai percorsi e vincoli generici usando tabelle di riferimento standardizzate.
  • Implementare comportamenti standard: automatizzare l'implementazione dei trait Debug, Clone, Eq, Ord e Hash usando l'attributo derive.
  • Ottimizzare il flusso di lavoro di sviluppo: utilizzare rustfmt, rustfix e Clippy per formattare, riparare e analizzare il codice secondo gli standard della community.