Salta ai contenuti

Tipi di dati in Rust

Ogni valore in Rust ha un tipo: un’etichetta che dice al compilatore che genere di dato è (un numero intero, un decimale, del testo, vero/falso e così via). Conoscere il tipo permette a Rust di controllare il tuo codice in cerca di errori prima che venga eseguito.

Come hai visto con le variabili, di solito Rust sa dedurre il tipo da solo. Ma è utile conoscere i tipi principali per nome, perché li vedrai nei messaggi di errore e nelle firme delle funzioni.

Gli interi sono numeri senza parte decimale, come 42 o -7. Rust ha diversi tipi interi che si distinguono per dimensione e per il fatto di ammettere o no numeri negativi:

Tipo Con segno? Uso tipico
i32 Sì (può essere negativo) Il default: usalo a meno che tu non abbia un motivo per non farlo
u32 No (da 0 in su) Conteggi, dimensioni, cose che non possono essere negative
i64 / u64 Sì / No Numeri molto grandi
usize No Indici nelle collezioni
fn main() {
let temperature = -5; // i32 per default
let count: u32 = 100; // esplicitamente senza segno
println!("{temperature} gradi, il conteggio è {count}");
}

Output:

-5 gradi, il conteggio è 100
▶ Provalo tu

Per i numeri con la virgola, usa i tipi in virgola mobile (floating point). Ce ne sono due: f64 (il default, a doppia precisione) e f32.

fn main() {
let pi = 3.14159; // f64 per default
let price: f32 = 9.99;
println!("Pi greco vale {pi}, il prezzo è {price}");
}

Output:

Pi greco vale 3.14159, il prezzo è 9.99
▶ Provalo tu

Nel codice, il separatore decimale è sempre il punto (3.14), non la virgola. Resta su f64 a meno che tu non abbia bisogno proprio del più piccolo f32: è più preciso e sull’hardware moderno è altrettanto veloce.

Un booleano (bool) è il tipo più semplice: vale true (vero) oppure false (falso). Li userai di continuo negli if e nelle condizioni.

fn main() {
let is_logged_in = true;
let has_permission: bool = false;
println!("connesso: {is_logged_in}, permesso: {has_permission}");
}

Output:

connesso: true, permesso: false
▶ Provalo tu

Un char contiene un singolo carattere, scritto tra apici singoli ' '. Un char di Rust può essere qualsiasi singolo valore scalare Unicode: questo copre la maggior parte delle emoji, anche se alcune più complesse (come le bandiere o le emoji formate da più caratteri uniti) non ci stanno in uno solo.

fn main() {
let letter = 'R';
let symbol = '$';
let crab = '🦀';
println!("{letter} {symbol} {crab}");
}

Output:

R $ 🦀
▶ Provalo tu

In Rust il testo si scrive tra virgolette doppie. Ci sono due tipi di stringa che incontrerai:

  • &str: una slice di stringa, di solito testo che scrivi direttamente nel codice (un «letterale stringa»).
  • String: un testo posseduto, che può crescere, e che puoi modificare e costruire pezzo per pezzo.
fn main() {
let greeting = "Ciao"; // &str
let mut name = String::from("Ferris"); // String
name.push_str(" il granchio"); // le String possono crescere
println!("{greeting}, {name}!");
}

Output:

Ciao, Ferris il granchio!
▶ Provalo tu

Non preoccuparti ancora della differenza tra &str e String: è legata all’ownership (possesso), che imparerai presto. Per ora: usa "..." per il testo e passa a String quando devi costruirlo o modificarlo.

Il più delle volte Rust deduce il tipo. Ma a volte ha bisogno di un indizio, per esempio quando trasformi del testo in un numero (lo vedrai nella pagina Conversione di tipo). Aggiungi un tipo con i due punti:

let x: i32 = 42;
let y: f64 = 3.5;
let active: bool = true;
Tipo Cosa contiene Esempio
i32 Numero intero (default) let n = 42;
u32 Numero intero non negativo let n: u32 = 42;
f64 Numero decimale (default) let pi = 3.14;
bool true o false let ok = true;
char Un carattere let c = 'A';
&str Testo letterale let s = "hi";
String Testo che può crescere let s = String::from("hi");

Descrivi un personaggio di un gioco con una variabile per tipo: un nome (&str), un livello (i32), una percentuale di salute (f64), un indicatore is_online (bool) e una lettera di grado (char). Stampali tutti su una riga. Suggerimento: un char usa gli apici singoli, il testo le virgolette doppie.

Mostra la soluzione
fn main() {
let name = "Ferris"; // &str
let level = 7; // i32
let health = 82.5; // f64
let is_online = true; // bool
let rank = 'A'; // char
println!("{name} | livello {level} | {health}% | online: {is_online} | grado {rank}");
}

Output:

Ferris | livello 7 | 82.5% | online: true | grado A
▶ Provalo tu

Parti da String::from("Rust"), poi aggiungi " è veloce" e " e sicuro", e stampa il risultato. Suggerimento: la String deve essere dichiarata con mut perché push_str possa modificarla.

Mostra la soluzione
fn main() {
let mut sentence = String::from("Rust");
sentence.push_str(" è veloce");
sentence.push_str(" e sicuro");
println!("{sentence}");
}

Output:

Rust è veloce e sicuro
▶ Provalo tu
  • Ogni valore ha un tipo; di solito Rust lo deduce.
  • Numeri interi → i32 (default). Decimali → f64 (default).
  • bool vale true/false; char è un singolo carattere tra apici singoli.
  • Il testo si scrive tra virgolette doppie: &str per i letterali, String per il testo che può crescere.

Verifica veloce

1. Qual è il tipo intero predefinito in Rust, se non ne indichi uno?

2. Come distingue Rust un letterale char da un letterale stringa?

3. Quale tipo è un testo posseduto, che può crescere e che puoi modificare?

4. Qual è il tipo in virgola mobile predefinito in Rust?

5. Quale tipo dedurrebbe Rust per let greeting = "Hello";?

Punteggio: 0 / 5