Salta ai contenuti

Stringhe in Rust

La gestione del testo è uno dei primi punti in cui Rust sembra diverso dagli altri linguaggi, soprattutto perché ha due tipi di stringa. Una volta capito il perché, smette di confondere.

  • &str («string slice», slice di stringa): testo che esiste già da qualche parte, di solito scritto direttamente nel codice. Ha dimensione fissa, non può crescere.
  • String: un testo posseduto, che può crescere. Puoi aggiungerci cose, e vive sull’heap.
fn main() {
let literal: &str = "ciao"; // una slice di stringa
let owned: String = String::from("ciao"); // una String posseduta
println!("{literal} / {owned}");
}
▶ Provalo tu

Una regola pratica semplice: se stampi solo testo fisso, "così" (un &str) va benissimo. Se devi costruire, allungare o modificare del testo durante l’esecuzione, usa String.

fn main() {
let mut greeting = String::from("Ciao");
greeting.push_str(", mondo"); // aggiunge un &str
greeting.push('!'); // aggiunge un singolo char
println!("{greeting}");
}

Output:

Ciao, mondo!
▶ Provalo tu

Puoi unire le stringhe con +, oppure usare format! (che di solito è l’opzione più chiara):

fn main() {
let first = String::from("Ciao, ");
let second = String::from("mondo!");
let combined = first + &second; // nota la & prima di second
println!("{combined}");
// format! spesso si legge meglio:
let name = "Ferris";
let greeting = format!("Ciao, {name}!");
println!("{greeting}");
}
▶ Provalo tu

Una manciata di metodi che userai di continuo:

fn main() {
let text = " Ciao, Rust! ";
println!("{}", text.trim()); // "Ciao, Rust!" (senza spazi ai lati)
println!("{}", text.to_uppercase()); // " CIAO, RUST! "
println!("{}", text.to_lowercase()); // " ciao, rust! "
println!("{}", text.contains("Rust")); // true
println!("{}", text.trim().len()); // 11 (lunghezza in byte)
println!("{}", text.trim().replace("Rust", "mondo")); // "Ciao, mondo!"
}
▶ Provalo tu

Per andare carattere per carattere, usa .chars():

fn main() {
for c in "abc".chars() {
println!("{c}");
}
}
▶ Provalo tu

Qualcuno ha scritto " rUsT mi PIACE " in un modulo. Trasformalo in rust mi diverte: togli gli spazi in più, rendi tutto minuscolo e sostituisci piace con diverte. Poi stampa il risultato e la sua lunghezza. Suggerimento: i metodi delle stringhe si possono concatenare, uno dopo l’altro: text.trim().to_lowercase()....

Mostra la soluzione
fn main() {
let input = " rUsT mi PIACE ";
// prima trim, poi minuscolo, poi sostituisci "piace" (ora minuscolo)
let clean = input.trim().to_lowercase().replace("piace", "diverte");
println!("{clean}");
println!("{} byte", clean.len());
}

Output:

rust mi diverte
15 byte
▶ Provalo tu

L’ordine conta: se chiamassi .replace("piace", "diverte") prima di .to_lowercase(), non verrebbe sostituito niente, perché il testo direbbe ancora PIACE. (Qui abbiamo evitato le lettere accentate apposta: occupano 2 byte ciascuna e cambierebbero il risultato di .len().)

Dati first = "Ada" e last = "Lovelace", costruisci la String [email protected] e stampala. Poi stampa se contiene una @. Suggerimento: format! può ricevere come argomenti per i suoi segnaposto {} espressioni come first.to_lowercase().

Mostra la soluzione
fn main() {
let first = "Ada";
let last = "Lovelace";
let email = format!("{}.{}@example.com", first.to_lowercase(), last.to_lowercase());
println!("{email}");
println!("sembra valida: {}", email.contains('@'));
}

Output:

sembra valida: true
▶ Provalo tu
  • &str è testo fisso preso in prestito; String è posseduta e può crescere.
  • Fai crescere una String con .push_str() (per del testo) o .push() (per un singolo carattere).
  • Per unire le stringhe preferisci format! a +: è più chiaro e non sposta niente.
  • Metodi comuni: .trim(), .to_uppercase(), .contains(), .replace(), .chars().

Verifica veloce

1. Quale tipo di stringa è posseduto e può crescere durante l'esecuzione?

2. Perché questa pagina preferisce format! a + quando si uniscono più di una o due stringhe?

3. Perché non puoi indicizzare una stringa Rust come text[0]?

4. Quale metodo aggiunge un singolo carattere a una String, come greeting.push('!')?

Punteggio: 0 / 4