Storicamente, uno dei principi di Rust era garantire la sicurezza dei tipi e l'assenza di conversioni implicite che portano a errori di esecuzione. Tuttavia, per comodità del codice, alcune conversioni automatiche parziali vengono implementate tramite deref coercion e i trait From/Into, al fine di semplificare il lavoro con i riferimenti, puntatori intelligenti e per consentire API universali.
Il problema si presenta quando le conversioni automatiche possono causare confusione, ad esempio quando si passa &String dove si aspetta &str. Viene chiamato Deref::deref nascosto, e a volte possono sorgere conseguenze impreviste (ad esempio, quando si modifica il tipo dei parametri passati). C'è anche la questione dei casting diretti e espliciti attraverso as.
Soluzione: Rust implementa regole severe di deref-coercion per i puntatori intelligenti (Box, Rc, Arc) e le stringhe (&String a &str, &Vec a &slice) a livello di compilazione. Per le conversioni esplicite, sono previsti i trait From, Into, TryFrom, TryInto e as per i casting di base. L'evitare errori è facilitato dalla tipizzazione statica e dai limiti delle conversioni implicite.
Esempio di codice:
fn print_text(text: &str) { println!("{}", text); } let s = String::from("Hello!"); print_text(&s); // s: String, &s: &String, coerzione automatica a &str
Caratteristiche chiave:
Funziona la deref coercion per tipi propri, se si implementa Deref manualmente?
Sì, se implementi il trait Deref per il tuo tipo, il compilatore sarà in grado di convertire automaticamente, ad esempio, il tuo wrapper nel tipo target all'interno della firma della funzione che si aspetta il corrispondente riferimento.
Può avvenire deref coercion per valori, e non per riferimenti?
No, la deref coercion automatica avviene solo quando si passano riferimenti, e solo quando il tipo implementa Deref.
Quali limitazioni ci sono nella conversione dei tipi tramite as quando si lavora con numeri e enum?
as non garantisce sicurezza: la conversione tra i tipi di numeri può causare overflow o perdita di dati, e per gli enum può portare a valori non semantici (ad esempio, a una variante enum non corretta).
Un principiante scrive una funzione che accetta &String e non può utilizzare &str direttamente, facendo sempre text.to_string() dalla stringa. Questo è sprecato in termini di memoria e prestazioni.
Vantaggi:
Svantaggi:
La funzione accetta un argomento di tipo &str, il che consente di essere chiamata con qualsiasi tipo che supporti dereferenziazione o conversione: &str, &String, letterali di stringa. Non sono necessarie allocazioni superflue.
Vantaggi:
Svantaggi: