Operatori Bitwise in Rust
Gli operatori bitwise in Rust manipolano i singoli bit dei tipi interi. Sono utili per flag, maschere di bit e ottimizzazioni a basso livello.
Operatori Disponibili
| Operatore | Nome | Descrizione |
|---|---|---|
& |
AND | 1 se entrambi i bit sono 1 |
| |
OR | 1 se almeno un bit è 1 |
^ |
XOR | 1 se i bit sono diversi |
! |
NOT | Inverte tutti i bit |
<< |
Shift sinistro | Sposta i bit a sinistra |
>> |
Shift destro | Sposta i bit a destra |
Esempi Base
fn main() {
let a: u8 = 0b1100; // 12
let b: u8 = 0b1010; // 10
println!("AND: {:08b} ({})", a & b, a & b); // 00001000 (8)
println!("OR: {:08b} ({})", a | b, a | b); // 00001110 (14)
println!("XOR: {:08b} ({})", a ^ b, a ^ b); // 00000110 (6)
println!("NOT: {:08b} ({})", !a, !a); // 11110011 (243)
println!("SHL: {:08b} ({})", a << 1, a << 1); // 00011000 (24)
println!("SHR: {:08b} ({})", a >> 1, a >> 1); // 00000110 (6)
}
Pattern: Flag con Bitmask
const LETTURA: u8 = 0b001; // 1
const SCRITTURA: u8 = 0b010; // 2
const ESECUZIONE: u8 = 0b100; // 4
fn main() {
let mut permessi: u8 = LETTURA | SCRITTURA; // 011
// Verifica permesso
if permessi & LETTURA != 0 {
println!("Ha permesso di lettura");
}
// Aggiungi permesso
permessi |= ESECUZIONE; // 111
// Rimuovi permesso
permessi &= !SCRITTURA; // 101
// Toggle permesso
permessi ^= LETTURA; // 100
println!("Permessi: {:03b}", permessi);
}
Shift per Potenze di 2
const KB: u64 = 1 << 10; // 1024
const MB: u64 = 1 << 20; // 1_048_576
const GB: u64 = 1 << 30; // 1_073_741_824
fn potenza_di_due(n: u32) -> u64 {
1u64 << n
}
Controllo Overflow
Rust controlla l’overflow degli shift in debug mode:
fn main() {
let x: u8 = 1;
// let y = x << 8; // PANIC in debug! Shift troppo grande per u8
let y = x.checked_shl(8); // None (sicuro)
let z = x.wrapping_shl(8); // 0 (wrapping)
}
Operatori Bitwise sui Tipi Personalizzati
use std::ops::BitOr;
#[derive(Debug, Clone, Copy)]
struct Permessi(u8);
impl BitOr for Permessi {
type Output = Self;
fn bitor(self, rhs: Self) -> Self {
Permessi(self.0 | rhs.0)
}
}
fn main() {
let lettura = Permessi(0b001);
let scrittura = Permessi(0b010);
let combinati = lettura | scrittura;
println!("{:?}", combinati); // Permessi(3)
}
Metodi Utili sui Tipi Interi
fn main() {
let n: u32 = 0b1010_1100;
println!("{}", n.count_ones()); // 4 (bit a 1)
println!("{}", n.count_zeros()); // 28 (bit a 0)
println!("{}", n.leading_zeros()); // 24
println!("{}", n.trailing_zeros()); // 2
println!("{}", n.rotate_left(2)); // Rotazione
println!("{}", n.reverse_bits()); // Inverti ordine bit
}
Conclusione
Gli operatori bitwise in Rust offrono controllo completo sui bit con la sicurezza tipica del linguaggio. Il controllo dell’overflow sugli shift e i metodi integrati sui tipi interi rendono le operazioni bitwise sia potenti che sicure. Usa i trait BitAnd, BitOr, BitXor, Not, Shl e Shr per implementarli sui tuoi tipi.