00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

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.