Shopping cart

0

Cart

  • 0 item

Nessun prodotto nel carrello.

All categories
 Corso Gratuita di Programmazione Rust Lezione 016 – Il Tipo di Fetta

SE VUOI PRENDERE LA CERTIFICAZIONE PER QUESTO CORSO CLICCA QUI

Il Tipo Slice

Gli slices ti permettono di fare riferimento a una sequenza contigua di elementi in una collezione anziché all’intera collezione. Un slice è una sorta di riferimento, quindi non possiede i dati.

Immagina di dover scrivere una funzione che trova la prima parola in una frase. Se la frase ha più parole separate da spazi, la funzione dovrebbe restituire solo la prima parola.

Iniziamo con una funzione che usa l’intera Stringa:

rust

fn first_word(s: &String) -> usize {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return i;
}
}

s.len()
}

Questa funzione controlla ogni carattere nella stringa finché non trova uno spazio. Restituisce quindi la posizione dello spazio, che corrisponde alla fine della prima parola. Se non trova spazi, restituisce la lunghezza totale della stringa, perché significa che la frase è composta da una sola parola.

Il problema di questa funzione è che restituisce un numero che rappresenta la posizione della fine della parola. Questo numero è valido solo per la stringa attuale. Se cambi la stringa dopo aver usato questa funzione, quel numero potrebbe non avere più senso. Per esempio:

rust

let mut s = String::from("ciao mondo");
let parola = first_word(&s); // "parola" avrà il valore 4
s.clear(); // ora la stringa è vuota

Dopo aver cancellato la stringa, il valore restituito da first_word non ha più senso perché non c’è più alcuna parola nella stringa. Questo può portare a bug difficili da individuare.

La soluzione a questo problema sono gli slices di stringhe. Gli slices permettono di fare riferimento solo a una parte della stringa originale, mantenendo un collegamento alla stringa completa. Così, se la stringa cambia, l’slice cambia automaticamente per riflettere la modifica.

Un altro vantaggio degli slices è che possono essere utilizzati sia con le Stringhe che con le stringhe letterali. Le stringhe letterali sono sequenze di caratteri scritte direttamente nel codice e sono immutabili.

rust

let s = String::from("ciao mondo");
let parola = &s[0..4]; // "parola" è uno slice della Stringa "ciao mondo"

In questo caso, “parola” è uno slice che punta alla parte di “ciao mondo” fino al quarto carattere, quindi “ciao”. Se modifichi la stringa originale, lo slice si adatta automaticamente. Ad esempio:

rust

let mut s = String::from("ciao mondo");
let parola = &s[0..4]; // "parola" punta a "ciao"
s.clear(); // ora la stringa è vuota
println!("La parola è: {}", parola); // Stampa "La parola è: "

Anche se hai cancellato la stringa, lo slice si è aggiornato di conseguenza. Questo rende gli slices molto più sicuri e affidabili rispetto alla semplice indicizzazione dei caratteri.

Stringhe Letterali come Slices

Ricorda quando abbiamo parlato delle stringhe letterali che vengono memorizzate all’interno del binario? Ora, con la conoscenza degli slices, possiamo capire meglio le stringhe letterali:

rust

let s = "Ciao, mondo!";

Il tipo di s qui è &str: è uno slice che punta a quel punto specifico del binario. Questo è anche il motivo per cui le stringhe letterali sono immutabili; &str è un riferimento immutabile.

Slices di Stringhe come Parametri

Sapendo che è possibile prendere slices di stringhe letterali e valori Stringa ci porta a un’altra miglioria per first_word, ed è la sua firma:

rust

fn first_word(s: &String) -> &str {

Un Rustacean più esperto scriverebbe invece la firma mostrata nel Listato 4-9 perché ci permette di usare la stessa funzione sia con valori &String che con valori &str.

rust

fn first_word(s: &str) -> &str {

Se abbiamo uno slice di stringa, possiamo passarlo direttamente. Se abbiamo una Stringa, possiamo passare uno slice della Stringa o un riferimento alla Stringa. Questa flessibilità sfrutta le coercizioni di dereferenziazione, una funzionalità che tratteremo nella sezione “Coercizioni di Dereferenziazione Implicite con Funzioni e Metodi” del Capitolo 15.

Definire una funzione per prendere uno slice di stringa invece di un riferimento a una Stringa rende la nostra API più generale e utile senza perdere alcuna funzionalità.

1 Comment

Leave a Reply

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *