Strumenti Utente

Strumenti Sito


programmazione:rust:appunti_sparsi

Curiosità e appunti vari sul linguaggio Rust

Autore: Fabio Di Matteo
Ultima revisione: 05/04/2026 19:24

Provenendo da altri linguaggi ho avuto qualche difficoltà ad abituarmi alla sintassi e buone pratiche incoraggiate dal Rust. Metto qualche appunto.

Blocco try/catch

In Rust il try/catch non esiste. Abbiamo i Result. Ecco alcune soluzioni al caso:

Esempio base

Creo una funzione che costruisce un errore e poi la uso in un blocco match:

use std::io;
 
fn divisione(a: i16, b: i16) -> Result<i16, io::Error> {
    if b == 0 {
        // Creiamo un errore I/O semplice per il caso di divisione per zero
        return Err(io::Error::new(io::ErrorKind::Other, "divisione per zero"));
    }
    Ok(a / b)
}
 
fn main() {
    match divisione(16, 0) {
        Ok(r) => {
            println!("Risultato: {}", r);
        }
        Err(err) => {
            eprintln!("Errore: {}", err);
        }
    }
    println!("Questo viene dopo.");
}

Altro esempio. Qui non restituisco un tipo di errore come errore, ma solo una stringa. Questo puo' essere piu' giusto nella validazione dei campi inseriti. In quanto potrebbe essere fuorviante stimolare un'errore io, altro.

fn maggiorenne(eta: i16) -> Result<bool, String> {
    if eta < 18 {
        return Err("Non sei maggiorenne".into());
    }
    Ok(true)
}
 
fn main() {
    match maggiorenne(4) {
        Ok(m) => {
            println!(
                "Perfetto, sei maggiorenne. Dunque la funzione restituisce {}",
                m
            );
        }
        Err(e) => {
            println!("Errore: {}", e);
        }
    }
 
    println!("Questo viene dopo. E fa parte del programma principale.");
}
.into() In poche parole prende un valore di un tipo e lo converte in un altro tipo, se esiste una conversione definita (tramite i trait From/Into). Qui prende &str e lo converte in String.

Con match su una funzione della libreria standard

use std::fs::File;
 
fn main() {
    match File::open("hello.txt") {
        Ok(f) => {
            println!("File aperto correttamente.");
            drop(f);
        }
        Err(err) => {
            eprintln!("Errore aprendo file: {}", err);
            return;
        }
    };
 
 
        println!("Qui siamo dopo.")
 
}

Con un semplice if

if let Ok(mut f) = File::open("a.txt") {
    /* successo */
} else {
    /* gestione fallimento */
}

Con is_ok/ is_err

let r = File::open("foo.txt");
if r.is_err() {
    eprintln!("Errore aprendo file: {:?}", r.err().unwrap());
} else {
    let mut f = r.unwrap();
    // usa f
}

Crosscompilare applicazioni

Alcuni comandi utili nella crosscompilazione per altre architetture. Per installare i vari pacchetti useremo rustup

Elencare i target installabili e installarne uno

Con il seguente comando vedremo i target installabili e quelli già installati.

rustup target list

E' possibile installarne uno con

rustup target add <target di mia scelta>

Per esempio:

rustup target add x86_64-pc-windows-gnu

In questo esempio installo il target per le crosscompilazioni su windows con mingw64. Quindi è richiesto in questo caso l'installazione di mingw .

Compilare il nostro progetto per target prescelto

Se vogliamo compilare il nostro progetto possiamo farlo con il seguente comando:

cargo build --target=<target di mia scelta>

come per esempio:

cargo build --target=x86_64-unknown-linux-musl

Quest'ultimo esempio mi genera un eseguibile statico per linux x86_64 grazie alla libreria musl.

Note sulla crosscompilazione per arm64

E' necessario installare il compilatore gcc per arm64. Su Arch linux:

sudo pacman -S aarch64-linux-gnu-gcc aarch64-linux-gnu-binutils

e impostare alcune variabili d'ambiente per constringere rust a usare il linker di arm64:

export CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc

Crosscopilare con :

cargo build --target=aarch64-unknown-linux-gnu

Crosscompilare staticamente con musl per aarch64?

impostiamo queste variabili d'ambiente:

export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-gnu-gcc
export CC_aarch64_unknown_linux_musl=aarch64-linux-gnu-gcc

e compiliamo con :

cargo build --target=aarch64-unknown-linux-musl

assicurandoci prima di aver installato il target in sopraindicato.

Le classi

Un esempio minimo.

struct Persona {
    id: i16,
    name: String,
    surname: String,
}
 
impl Persona {
    fn new() -> Self {
        return Self {
            id: 0,
            name: "".into(),
            surname: "".into(),
        };
    }
    fn set(&mut self, id: i16, name: String, surname: String) {
        self.id = id;
        self.name = name;
        self.surname = surname;
    }
}
 
fn main() {
    let mut p = Persona::new();
    p.set(1, "Fabio".into(), "Di Matteo".into());
 
    println!("{} {} {}", p.id, p.name, p.surname);
}

Versione con l'aggiunta di un metodo “getter”:

struct Persona {
    id: i16,
    name: String,
    surname: String,
}
 
impl Persona {
    fn new() -> Self {
        return Self {
            id: 0,
            name: "".into(),
            surname: "".into(),
        };
    }
    fn set(&mut self, id: i16, name: String, surname: String) {
        self.id = id;
        self.name = name;
        self.surname = surname;
    }
 
    fn get(&self, op: String) -> String {
        if op == "name" {
            return self.name.clone();
        } else if op == "surname" {
            return self.surname.clone();
        } else {
            return self.id.to_string();
        }
    }
}
 
fn main() {
    let mut p = Persona::new();
    p.set(1, "Fabio".into(), "Di Matteo".into());
    let nome = p.get("name".into());
    let cognome = p.get("surname".into());
    let id = p.get("id".into());
 
    println!("{} {} {}", id, nome, cognome);
}

Sviluppo di programmi dotatati di gui

Di seguito le mmie esperienze:

programmazione/rust/appunti_sparsi.txt · Ultima modifica: 13/04/2026 14:44 da Fabio Di Matteo