Historisch gezien was een van de principes van Rust het waarborgen van typeveiligheid en het vermijden van impliciete conversies die tot runtime-fouten leiden. Maar voor de gebruiksvriendelijkheid van de code worden gedeeltelijke automatische conversies gerealiseerd via deref coercion en de From/Into-traits, om het werken met verwijzingen, slimme pointers en universele API's te vereenvoudigen.
Het probleem doet zich voor wanneer automatische conversies verwarring kunnen veroorzaken, bijvoorbeeld wanneer je &String doorgeeft waar &str wordt verwacht. Er wordt een verborgen Deref::deref aangeroepen, en soms ontstaan er onvoorziene gevolgen (zoals bij het wijzigen van het type van doorgegeven parameters). Daarnaast is er de vraag van directe en expliciete casting via as.
Oplossing: Rust implementeert strikte regels voor deref-coercion voor slimme pointers (Box, Rc, Arc) en strings (&String naar &str, &Vec naar &slice) op het niveau van de compiler. Voor expliciete conversies zijn er traits zoals From, Into, TryFrom, TryInto, as voor basis-casts. Fouten kunnen worden vermeden door statische typecontrole en het beperken van impliciete conversies.
Codevoorbeeld:
fn print_text(text: &str) { println!("{}", text); } let s = String::from("Hello!"); print_text(&s); // s: String, &s: &String, automatische coercie naar &str
Belangrijke kenmerken:
Werkt deref coercion voor eigen types, als je Deref handmatig implementeert?
Ja, als je de trait Deref voor je type implementeert, kan de compiler automatisch converteren, bijvoorbeeld je wrapper naar het doeltype binnen de signatuur van een functie die de overeenkomstige referentie verwacht.
Kan deref coercion plaatsvinden voor waarden, en niet voor referenties?
Nee, automatisch dereferenceren gebeurt alleen bij het doorgeven van referenties, en alleen wanneer het type Deref implementeert.
Wat zijn de beperkingen van typecasting via as bij het werken met getallen en enums?
as garandeert niet de veiligheid: conversie tussen type getallen kan leiden tot overflow of dataverlies, en voor enums kan het leiden tot niet-semantische waarden (bijvoorbeeld naar een onjuiste enum variant).
Een beginner schrijft een functie die &String accepteert en kan niet rechtstreeks &str gebruiken, doet overal text.to_string() van de string. Dit is verspilling van geheugen en prestaties.
Voordelen:
Nadelen:
Een functie accepteert een argument van het type &str, waardoor het kan worden aangeroepen met elk type dat derefereren of conversie ondersteunt: &str, &String, stringliteralen. Geen overbodige allocaties nodig.
Voordelen:
Nadelen: