Rust:
Rifattorizzazione

Come fare:

Rifacciamo il refactoring di un semplice pezzo di codice Rust per renderlo più idiomatico e manutenibile. Iniziamo con una funzione che calcola la somma di un vettore di interi:

fn sum(vec: &Vec<i32>) -> i32 {
    let mut sum = 0;
    for i in vec {
        sum += i;
    }
    sum
}

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    println!("La somma è {}", sum(&numbers));
}

Output:

La somma è 15

Ora, rifacciamo il refactoring per usare Rust più idiomatico sfruttando gli iteratori e il metodo fold:

fn sum(vec: &[i32]) -> i32 {
    vec.iter().fold(0, |acc, &x| acc + x)
}

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    println!("La somma è {}", sum(&numbers));
}

Nessun cambiamento nell’output—è ancora 15—ma la versione refactorizzata è più pulita e sfrutta i punti di forza di Rust come il prestito e i metodi degli iteratori.

Approfondimento

Il Refactoring ha le sue radici nella comunità di Smalltalk ed è stato reso popolare nel mondo Java dal libro di Martin Fowler “Refactoring: Improving the Design of Existing Code”. I suoi principi sono universali e si applicano anche a Rust, dove la sicurezza e la concorrenza sono di fondamentale importanza. Rust incoraggia la scrittura di codice robusto intercettando i problemi al momento della compilazione, quindi durante il refactoring, il compilatore di Rust agisce come una rete di sicurezza.

Alternative al refactoring manuale includono l’uso di strumenti automatizzati, come ‘rustfmt’ per la formattazione del codice e ‘clippy’ per il linting, che possono suggerire modi più idiomatici di scrivere codice. Tuttavia, il refactoring approfondito spesso richiede una comprensione riflessiva del design del codice, che questi strumenti non possono automatizzare completamente.

In Rust, il refactoring potrebbe ruotare attorno al miglioramento dell’uso dei tipi, sfruttando efficacemente i lifetimes, riducendo le allocazioni non necessarie o impiegando modelli di concorrenza come l’uso di Arc<Mutex<T>> quando necessario. È anche comune passare da unwrap() a una gestione degli errori più espressiva con Result<T, E>.

Vedi Anche

Per approfondire il refactoring in Rust: