Salta ai contenuti

Booleani in Rust

Un booleano è il tipo più semplice che esista: può valere solo true (vero) o false (falso). In Rust si chiama bool, e lo userai ovunque nel codice ci sia una decisione da prendere.

fn main() {
let is_active = true;
let has_error: bool = false;
println!("attivo: {is_active}, errore: {has_error}");
}
▶ Provalo tu

Rust deduce quasi sempre da solo il tipo bool a partire da true/false, quindi raramente devi scriverlo in modo esplicito.

Nel codice reale non scrivi spesso true o false direttamente: di solito arrivano dal confronto di qualcosa:

fn main() {
let age = 20;
let can_vote = age >= 18;
println!("Può votare: {can_vote}");
}

Output:

Può votare: true
▶ Provalo tu

Il compito principale di un bool è decidere quale ramo di un if eseguire:

fn main() {
let is_raining = true;
if is_raining {
println!("Prendi l'ombrello");
} else {
println!("Lascialo a casa");
}
}

Vediamo if per bene nella pagina If…else: questo è solo un assaggio del perché i booleani contano.

Hai conosciuto && (e), || (o) e ! (non) nella pagina Operatori. C’è un’altra cosa da sapere: si fermano prima quando la risposta è già decisa. Si chiama valutazione a corto circuito (short-circuit).

  • Con a && b, se a è false, il tutto deve essere false, quindi Rust non guarda mai b.
  • Con a || b, se a è true, il tutto deve essere true, quindi Rust non guarda mai b.

Non è solo un trucco per andare più veloci. Permette al lato sinistro di proteggere il lato destro:

fn main() {
let count = 0;
let total = 50;
// count vale 0, quindi Rust si ferma dopo `count != 0` e non divide mai.
let big_average = count != 0 && total / count > 10;
println!("media alta: {big_average}");
let is_weekend = true;
let has_homework = true;
// is_weekend è true, quindi `!has_homework` non viene mai controllato.
let can_relax = is_weekend || !has_homework;
println!("posso rilassarmi: {can_relax}");
}

Output:

media alta: false
posso rilassarmi: true
▶ Provalo tu

Dividere per zero manderebbe in crash il programma. Siccome count != 0 viene prima ed è false, la divisione semplicemente non viene mai eseguita. Inverti i due lati (total / count > 10 && count != 0) e la divisione verrebbe eseguita per prima. In questo caso il compilatore se ne accorge perfino e si rifiuta di compilare («this operation will panic at runtime», cioè questa operazione andrà in panic durante l’esecuzione); con un valore che arriva solo mentre il programma gira, invece, andrebbe in crash. Quindi metti il «controllo di sicurezza» a sinistra.

Un’attrazione di un parco divertimenti ti fa salire se sei alto almeno 120 cm, oppure se hai almeno 8 anni e sei accompagnato da un adulto. Salva un’altezza di 115, un’età di 9 e with_adult = true, poi stampa se questo bambino può salire. Suggerimento: usa le parentesi per raggruppare la parte «età e adulto».

Mostra la soluzione
fn main() {
let height_cm = 115;
let age = 9;
let with_adult = true;
let tall_enough = height_cm >= 120;
let can_ride = tall_enough || (age >= 8 && with_adult);
println!("abbastanza alto: {tall_enough}");
println!("può salire: {can_ride}");
}

Output:

abbastanza alto: false
può salire: true
▶ Provalo tu

Un anno è bisestile se è divisibile per 4 ma non per 100, oppure se è divisibile per 400. Calcola un booleano is_leap per il 2024, stampalo, poi fai lo stesso per il 1900. Suggerimento: «divisibile per 4» si scrive year % 4 == 0, e puoi fare lo shadowing di year e is_leap con un secondo let.

Mostra la soluzione
fn main() {
let year = 2024;
let is_leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
println!("{year} è bisestile: {is_leap}");
let year = 1900;
let is_leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
println!("{year} è bisestile: {is_leap}");
}

Output:

2024 è bisestile: true
1900 è bisestile: false
▶ Provalo tu
  • bool contiene esattamente due valori: true o false.
  • I confronti (==, <, >=, …) producono booleani.
  • Le condizioni negli if devono essere un vero bool: nessuna conversione implicita da numeri o stringhe.
  • && e || fanno il corto circuito: saltano il lato destro quando la risposta è già nota, quindi metti i controlli di sicurezza a sinistra.

Verifica veloce

1. Che tipo produce un confronto come age >= 18?

2. In Rust puoi usare un intero come 0 direttamente come condizione di un if, come in altri linguaggi?

3. In count != 0 && total / count > 10, cosa succede quando count vale 0?

Punteggio: 0 / 3