Le stringhe in Rust

Vediamo cosa quali tipi di dato ci permettono di lavorare con le stringhe in Rust e come rispettare le regole di proprietà e riferimento.

In Rust possiamo gestire le stringhe in due modi. Se ci servono dati immediati, non modificabili e da lavorare subito, possiamo usare le stringhe letterali o slice. Se ci servono dati dinamici da conservare in memoria, possiamo usare il tipo String.

Le stringhe sono collezioni di byte, ciascuno dei quali rappresenta un carattere ASCII. Inoltre, i caratteri vengono codificati in UTF-8, un sistema a 8 bit (1 byte) che ci permette di rappresentare caratteri UNICODE, che sono formati anche fino a 4 byte. In questo modo possiamo gestire le emoji e i simboli delle varie lingue straniere.

Le stringhe slice possono essere create semplicemente scrivendo il testo come valore della variabile. Il tipo String essendo una struct, va creato tramite le funzioni come String::new() se non vogliamo avere nessun valore iniziale o direttamente con String::from(‘testo’), per avere un valore. Possiamo usare String::from e metodi simili in qualunque punto del nostro codice.

Per capire bene l’utilizzo di questi due tipi è importante conoscere le regole di ownership e di borrowing di Rust, che riguardano le regole di proprietà e di riferimento dei dati conservati in memoria.

Conversione da slice a stringhe

Possiamo convertire una slice in String con il metodo .to_string().


fn main() {
    let string_slice = "Hello 3: 😊";
    
    let string = string_slice.to_string();

    println!("{}",string)
    
}

Conversione da String a slice

Possiamo convertire una stringa in slice usiamo il metodo .to_str() oppure usando gli altri metodi per le slice. 


fn main() {
    let string = String::from("Hello 3: 😊");
    
    let string_slice = string.as_str();

    println!("{}",string_slice)
    
}

Possiamo passare automaticamente un riferimento &str tramite una String.


fn main() {
    let string = String::from("Hello 3: 😊");
    
    show_str(&string);
}


fn show_str(string:&str) {
    println!("{}",string)
}

Conversione in caratteri e in bytes

Possiamo facilmente iterare ogni elemento di una stringa in caratteri e in byte. Possiamo poi stamparli su schermo.


fn main() {
    let s = "Hello 3: 😊";
    
    for char in s.chars() {
        println!("Char: '{}'",char);
        for byte in char.to_string().bytes() {
            println!("  Byte: {}",byte);
        }
    }
}

Possiamo anche creare una funzione esterna che riceve le stringhe da convertire in byte.

fn main() {
    let s = "Hello 3: 😊";
    
    show_bytes(&s);
}

fn show_bytes(string: &str) {
    for char in string.chars() {
        println!("Char: '{}'",char);
        for byte in char.to_string().bytes() {
            println!("  Byte: {}",byte);
        }
    } 
}