7 motivi per usare Rust per il tuo prossimo progetto di sviluppo

Sei uno sviluppatore che vuole imparare Rust? Per aiutarti a decidere, questo articolo presenta alcune delle caratteristiche di Rust, uno dei linguaggi di programmazione per sistemi più popolari.

In questo articolo esploreremo il linguaggio di programmazione Rust e le sue caratteristiche, come il sistema dei tipi, la sicurezza della memoria e la proprietà. Esamineremo anche un elenco di risorse che possono aiutarti a imparare Rust.

Cominciamo!

Cos’è la ruggine?

Rust è un linguaggio di programmazione dei sistemi. È iniziato come un progetto personale di Graydon Hoare, uno sviluppatore, nel 2006. In meno di un decennio, è diventato la scelta ideale per la programmazione di sistemi e le applicazioni affini. Lo stipendio medio di un programmatore Rust è di circa $ 120.000.

Quindi, se stai cercando di passare da C++ a Rust o stai cercando di imparare un nuovo linguaggio, imparare Rust può essere un’ottima scelta! Secondo il sondaggio StackOverflow Developer, Rust è stato votato come il linguaggio di programmazione più amato, per sette anni consecutivi.

Fonte immagine: StackOverflow

Rust offre la velocità dei linguaggi di programmazione di sistemi di basso livello come C e C++ e la sicurezza dei linguaggi di programmazione di alto livello come Python.

Da progetti importanti come Dropbox e Firefox a WebAssembly e programmazione incorporata, Rust è ampiamente utilizzato in tutte le aree dello sviluppo software. Rust offre un supporto immediato per la gestione dei pacchi tramite Cargo.

Cargo: il gestore dei pacchetti per Rust

Cargo è il gestore di pacchetti per Rust. Puoi usare cargo per installare i pacchetti da crates, il registro dei pacchetti di Rust. Oltre ad essere un gestore di pacchetti che ti consente di cercare, installare e gestire pacchetti, cargo funge anche da test runner, generatore di documenti e sistema di compilazione.

Ora che hai una panoramica di Rust, diamo un’occhiata più da vicino ad alcune delle caratteristiche di Rust che lo distinguono come linguaggio di programmazione di sistemi con ampia adozione.

Messaggi di errore utili

Come programmatore principiante, ti imbatterai in errori e passerai una notevole quantità di tempo a eseguire il debug del tuo codice. Utilizzerai i messaggi di errore e gli avvisi forniti dal compilatore per risolvere questi problemi. E messaggi utili possono aiutarti a eseguire il debug più velocemente.

Un esempio di messaggio di errore

Quando il tuo codice non viene compilato correttamente, Rust fornisce utili messaggi di errore che forniscono spiegazioni su cosa deve essere corretto nel tuo codice e dove.

In questo esempio, la variabile num2 è definita all’interno della funzione inner(). È quindi limitato all’ambito della funzione. Se provi ad accedervi al di fuori della funzione, il compilatore genera un errore:

fn main() {
    let num1 = 10;
    fn inner(){
        let num2 = 9; 
    }
    println!("The value of num2 is: {}", num2);
}

E il messaggio di errore fornisce informazioni su ciò che deve essere risolto.

error[E0425]: cannot find value `num2` in this scope
 --> src/main.rs:6:42
  |
6 |     println!("The value of num2 is: {}", num2);
  |                                          ^^^^ help: a local variable with a similar name exists: `num1`

Avvertenze durante la compilazione

Il compilatore fornisce anche avvisi utili relativi ai problemi nel codice. Quando definisci delle variabili ma non le usi mai nel resto del programma, Rust ti dà un messaggio di avviso, come mostrato.

fn main() {
    let num1 = 10;
    let num2 = 9;
    println!("The value of num1 is: {}", num1);
}

Qui la variabile num2 è dichiarata ma mai utilizzata.

warning: unused variable: `num2`
 --> src/main.rs:3:9
  |
3 |     let num2 = 9;
  |         ^^^^ help: if this is intentional, prefix it with an underscore: `_num2`
  |

Linguaggio fortemente tipizzato

Un altro motivo per cui dovresti usare Rust per i tuoi progetti di sviluppo è il suo sistema di tipi. Rust è un linguaggio fortemente tipizzato, il che significa che non supporta la coercizione di tipo. La coercizione del tipo è quando un linguaggio può convertire implicitamente un valore in un tipo di dati in un altro.

Ad esempio, il codice Python nella cella di codice seguente verrà eseguito senza errori. Questo perché in Python un numero diverso da zero ha un valore di verità True e, pertanto, l’istruzione if viene eseguita senza errori, anche se il numero 10 è un numero intero e non un valore booleano.

num1 = 10
if num1:
    num2 = 9
print(f"num2 is {num2}")

# Output: num2 is 9

D’altra parte, Rust non costringe i tipi. Quindi il seguente codice genererà un errore:

fn main() {
    let num1 = 10;
    if num1{
        let num2 = 9; 
    }
}

L’errore segnala una mancata corrispondenza di tipo, in cui era previsto un valore booleano ed è stato trovato un numero intero.

error[E0308]: mismatched types
 --> src/main.rs:3:8
  |
3 |     if num1{
  |        ^^^^ expected `bool`, found integer

Sicurezza della memoria

La sicurezza della memoria è un’altra caratteristica di Rust che lo rende interessante per i programmatori. Cercheremo di fornire una rapida panoramica di come funziona.

Le variabili devono essere inizializzate prima di essere utilizzate

In Rust, tutte le variabili devono essere inizializzate prima di poter essere utilizzate. In linguaggi come C, il seguente codice in cui num non è inizializzato verrà compilato ed eseguito senza errori. Il valore della variabile non inizializzata è un valore spazzatura.

#include <stdio.h>

int main(void) {
    int num;
	printf("The value of num is %d", num);
	return 0;
}
// Output: The value of num is 0

Se provi a fare qualcosa di simile in Rust, ti imbatterai in un errore in fase di compilazione. Rust, quindi, non ha alcuna nozione di garbage collection.

fn main() {
    let num:i32;
    println!("The value of num is: {}",num);
}
error[E0381]: used binding `num` isn't initialized
 --> src/main.rs:3:40
  |
2 |     let num:i32;
  |         --- binding declared here but left uninitialized
3 |     println!("The value of num is: {}",num);
  |                                        ^^^ `num` used here but it isn't initialized
  |

Sicurezza della memoria in fase di compilazione

Rust garantisce la sicurezza della memoria in fase di compilazione. Facciamo un semplice esempio. Qui, anche se l’istruzione condizionale if ha un valore booleano true, il che significa che il valore di num sarà sempre 100, otteniamo un errore quando proviamo a stampare il valore di num.

fn main() {
    let num:i32;
    if true{
        num = 100;
    }
    println!("The value of num is: {}", num);
}

Questo perché la valutazione condizionale si verifica in fase di esecuzione e il compilatore non sarà in grado di garantire che num abbia un valore in fase di compilazione.

error[E0381]: used binding `num` is possibly-uninitialized
 --> src/main.rs:6:41
  |
2 |     let num:i32;
  |         --- binding declared here but left uninitialized
3 |     if true{
  |        ---- if this `if` condition is `false`, `num` is not initialized
4 |         num = 100;
5 |     }
  |      - an `else` arm might be missing here, initializing `num`
6 |     println!("The value of num is: {}", num);
  |                                         ^^^ `num` used here but it is possibly-uninitialized

Se dai un’occhiata più da vicino al messaggio di errore, vedrai che con un’istruzione else, possiamo garantire che num avrà un valore. Quindi il codice seguente verrà eseguito senza errori. Perché in questo modo, il compilatore può determinare che num avrà un valore, in fase di compilazione, quindi non ci saranno errori.

fn main() {
    let num:i32;
    if true{
        num = 100;
    }
    else{
        num = 50;
    }
    println!("The value of num is: {}", num);
}
The value of num is: 100

Immutabilità delle variabili

È anche utile notare che le variabili in Rust sono immutabili per impostazione predefinita. Ciò significa che come sviluppatore non devi preoccuparti di sovrascrivere accidentalmente il valore di una particolare variabile. Ecco un esempio:

fn main() {
    let num1 = 10;
    num1 = 5;
    println!("The value of num1 is: {}", num1);
}

Poiché num1 è inizializzato a 10, quando provi ad assegnargli un valore di 5, ricevi un messaggio di errore che dice “impossibile assegnare due volte alla variabile immutabile num1”.

error[E0384]: cannot assign twice to immutable variable `num1`
 --> src/main.rs:3:5
  |
2 |     let num1 = 10;
  |         ----
  |         |
  |         first assignment to `num1`
  |         help: consider making this binding mutable: `mut num1`
3 |     num1 = 5;
  |     ^^^^^^^^ cannot assign twice to immutable variable

Proprietà e prestito

La proprietà garantisce la sicurezza della memoria. Funzionalmente, la proprietà in Rust può essere riassunta come segue:

Ogni oggetto dovrebbe avere uno e un solo proprietario. Se il proprietario esce dall’ambito, l’oggetto viene eliminato.

Facciamo un semplice esempio. Qui inizializziamo una stringa str1 e quindi spostiamo il suo valore in str2. Poiché ogni oggetto può avere un solo proprietario, l’oggetto str1 viene eliminato non appena il suo valore viene spostato in str2.

fn main() {
    let str1 = String::from("Rust");
    let str2 = str1;
    println!("The value of str1 is: {}", str1);
}
error[E0382]: borrow of moved value: `str1`
 --> src/main.rs:4:42
  |
2 |     let str1 = String::from("Rust");
  |         ---- move occurs because `str1` has type `String`, which does not implement the `Copy` trait
3 |     let str2 = str1;
  |                ---- value moved here
4 |     println!("The value of str1 is: {}", str1);
  |                                          ^^^^ value borrowed here after move

Anche se questo sembra intuitivo, per comprendere e apprezzare meglio come funziona la proprietà, è utile apprendere i concetti di prestito e riferimenti.

Sviluppo rapido

Finora abbiamo discusso diverse utili funzionalità del linguaggio di programmazione Rust. Per esaminarne alcuni:

  • Rust è ottimizzato sia per la velocità che per la sicurezza.
  • Viene fornito con uno strumento di gestione dei pacchetti integrato e crea un sistema.
  • Ha anche una ricca libreria standard.

In sostanza, Rust offre tutto ciò che uno sviluppatore può chiedere. Pertanto, con Rust, puoi sviluppare rapidamente applicazioni con debug minimi e build più veloci.

Sviluppo multipiattaforma

Con Rust, puoi scegliere di sviluppare su una piattaforma a tua scelta. Rust supporta le piattaforme più comuni: Linux, MacOS e Windows.

Lo sviluppo dell’applicazione è generalmente semplice in quanto è possibile compilare il codice sorgente di Rust in un eseguibile senza dipendere da altri strumenti di compilazione e compilatori esterni.

Una comunità di supporto fa molto per semplificare il tuo percorso di apprendimento. Rust ha un’enorme base di utenti che cresce ogni anno che passa.

La popolarità di Rust nel sondaggio degli sviluppatori di StackOverflow indica che esiste una vasta comunità di utenti, con molti sviluppatori esperti disposti a condividere le proprie conoscenze e competenze.

Oltre alla documentazione ufficiale, esiste anche un sito di documentazione generato dall’utente e un forum di discussione. Puoi anche controllare i gruppi subreddit e LinkedIn di Rust per discussioni pertinenti.

Risorse di apprendimento per iniziare con Rust

Questa sezione elenca alcune risorse utili per aiutarti a iniziare con Rust. Questo non è un elenco esaustivo ma include alcuni tutorial, corsi e libri consigliati per aiutarti nel tuo percorso di apprendimento.

#1. Ruggine con l’esempio

Rust By Example ti insegnerà i fondamenti di Rust e le librerie standard attraverso una serie di esempi che puoi codificare in un editor online.

Gli argomenti trattati includono casse, carico: lo strumento di gestione dei pacchetti per Rust, generici, tratti, gestione degli errori e molto altro.

#2. Fruscii

Rustlings è un’altra risorsa di apprendimento ufficiale per il linguaggio di programmazione Rust. È simile a Rust per esempio. Tuttavia, richiede di configurare l’ambiente di sviluppo locale, clonare un repository di esempio e risolvere semplici problemi per apprendere questi concetti.

#3. Pista della ruggine di esercizio

The Rust Track on Exercism ha più di 100 esercizi per aiutarti a imparare e testare la tua comprensione di Rust. Exercism è una piattaforma gratuita in cui puoi essere guidato da programmatori esperti oltre a programmare la tua strada attraverso gli esercizi.

#4. Ultimate Rust Crash Course

Il corso Ultimate Rust Crash tenuto da Nathan Stocks su Udemy copre quanto segue:

  • Fondamenti della programmazione in Rust
  • Sistema di moduli in ruggine
  • Tipi di dati e flusso di controllo
  • Riferimento e prestito
  • Struct, tratti e collezioni

#5. Ultimate Rust 2: concetti intermedi

Ultimate Rust 2 è un corso successivo al corso Ultimate Rust Crash e copre i seguenti argomenti:

  • Chiusure
  • Iteratori
  • Gestione degli errori
  • Unità e test di integrazione
  • Logging, multithreading e canali

#6. Rust lang: la guida completa per principianti 2023

Questo corso Udemy tenuto da Catalin Stefan è un corso completo sulla programmazione Rust. Alcuni degli argomenti trattati includono:

  • Fondamenti di ruggine
  • Tipi di dati, strutture di controllo
  • Funzioni, tratti
  • Gestione della memoria
  • Concorrenza

#7. Programmazione di Rust: sviluppo di sistemi rapido e sicuro

Programming Rust di O’Reilly è un popolare libro di programmazione Rust che ti insegnerà quanto segue:

  • Tipi di dati fondamentali
  • Proprietà e prestito
  • Programmazione asincrona
  • Applicazioni multithread veloci
  • Chiusure, iteratori
  • Collezioni

#8. Il linguaggio di programmazione Rust, 2a edizione

Il linguaggio di programmazione Rust è stato scritto da rinomati contributori della comunità Rust. Questo libro copre tutto ciò che devi sapere su Rust, tra cui:

  • Proprietà e prestito
  • Generici, tratti
  • Puntatori intelligenti, multithreading
  • Test e gestione degli errori

#9. La guida di riferimento completa per la programmazione in Rust

La guida di riferimento completa alla programmazione di Rust di Packt copre quanto segue:

  • Implementazione di strutture dati in Rust
  • Scrivere componenti riutilizzabili e testabili in Rust
  • Progettazione di algoritmi di progettazione di applicazioni multithread e
  • Applicazioni di Rust in WebAssembly, networking e applicazioni a riga di comando

#10. Progetti creativi per programmatori Rust

Se sei uno sviluppatore esperto che sta imparando Rust, la creazione di alcuni progetti nel tuo dominio di interesse sarà sufficiente per acquisire una buona conoscenza della lingua. Creative Projects for Rust Programmers di Packt è un libro che insegna Rust applicandolo a progetti come:

  • Creazione di servizi Web Restful
  • Giochi 2D con
  • Sviluppo di applicazioni Web tramite WebAssembly
  • Emulatori di linguaggio macchina
  • e altro ancora!

Conclusione

Questo articolo ha presentato una panoramica di Rust come linguaggio di programmazione dei sistemi, comprese funzionalità come la sicurezza della memoria, una migliore gestione dei pacchetti e altro ancora. Abbiamo anche elencato le risorse di apprendimento per aiutarti a diventare operativo con Rust.

Come passaggio successivo, puoi scegliere una o più delle risorse di apprendimento menzionate per apprendere le basi di Rust. Buona programmazione Rust!

Puoi anche esplorare alcuni dei migliori provider di hosting di server Rust.