|
I valori di tipo booleano, nella loro semplicità, sono tra i grandi protagonisti della programmazione. Si tratta tra l'altro, come evidenziato nel capitolo precedente, di uno dei tipi primitivi, built-in, del linguaggio. In Rust i valori ammessi sono due, come in molti altri linguaggi: * true * false vero e falso. Una variabile booleana si dichiara nel solito modo: let b1 = true: let b2: bool = false; let mut b3 = true; non sono ammessi altri valori ad esempio valori 0 e 1 che in altri linguaggi possono sostituirsi a true e false non sono consentiti. Questo è un bene. Vedremo comunque un esempio in fine paragrafo che chiarirà ulteriormente il rapporto tra interi e booleani. Come sempre, affinchè dette variabili siano modificabili è necessario che sia presente la solita keyword mut. Annotiamo che dal punto di vista tecnico una variabile booleana occupa lo spazio di un solo byte. In pratica basterebbe un bit ma in questo modo è possibile creare dei puntatori anche verso variabili booleane. Ora, una variabile dichiarata come negli esempi precedenti piuttosto raramente vi tornerà utile. Invece, nella maggioranza dei casi il valore booleano che tratterete sarà il risultato di una espressione ovvero una operazione di confronto. Vediamo quali sono gli operatori usati e chiariamo il concetto con un esempio:
Questi operatori danno origine ad espressioni il cui valore deve essere necessariamente vero o falso. Vediamo il seguente esempio:
che restituisce il seguente output:
Quando ci occuperemo delle istruzioni di selezione, che possono presentare naturalmente le più svariate casistiche, vedremo quanto importanti siano questi operatori. Sui valori booleani, true e false, è possibile compiere delle operazioni di carattere logico. Gli operatori principali sono i seguenti:
and true and true -> true true and false -> false false and true -> false false and false -> false or true or true -> true true or false -> true false or true -> true false or false -> false not not true -> false not false -> true xor true xor true -> false true xor false -> true false xor true -> true false xor false -> false == true == true -> true false == true -> false true == false -> false false == false -> true Il tipo bool essendo, come detto, primitivo in Rust implementa 5 trait fondamentali (oltre ad altri ancora): Clone, Copy, Sized, Send, Sync. Cosa questo significhi in dettaglio è materia molto più avanzata, per il momento diciamo che grazie al primo, siamo in grado di effetturare delle copie bit a bit. Il seguente codice crea due variabili booleane b1 e b2 che è copia di b1 ma da essa indipendente. fn main() { let mut b1 = true; let mut b2 = b1; b1 = false; print!("{}", b2); } b2 continua valere "true" mentre b1 è passato a false. Quindi b2 è del tutto staccato e indipendente da b1. Abbiamo detto che non è ammesso che valori numerici siano direttamente usati come booleani. E' tuttavia possibile effettuare una conversione da booleano ad intero mentre non è ammesso il contrario:
se escludiamo la riga 5, l'output è:
mentre reintroducendo la 5 si otterrebbe: error[E0054]: cannot cast `i32` as `bool` chiaro e forte. Quindi possiamo andare dai booleani verso gli interi ma non viceversa. Per quanto non utile nel nostro contesto segnalo anche la presenza di un crate che si chiama as_bool e fornisce un modo per rappresentare vari tipi in un contesto booleano. Esso si basa su una serie di regole:
Il suo uso, che necessita di qualche manipolazione un po' particolare, che fa necessariamente uso del file cargo.toml, esula da questa trattazione ma lo vedremo nella sezione degli esempi. I booleani internamente sono più complessi di quanto sembri e su di essi è possibile effettuare ulteriori manipolazioni (per fare un esempio i classici BitAnd e BitOr grazie ai trait omologhi che questo tipo implementa) che però esulano dalla finalità di base di questo paragrafo. |