In Rust is het toegestaan om een trait voor een type te implementeren alleen als:
Deze voorwaarden worden de weesregel (orphan rule) genoemd. Dit beschermt tegen conflicten in het geval van onafhankelijke implementaties van dezelfde trait voor hetzelfde type in verschillende crates.
Als je een externe trait voor een extern type wilt implementeren - is dat direct niet mogelijk. Gewoonlijk wordt het patroon van "newtype" gebruikt: het type in een eigen structuur binnen de crate verpakken en vervolgens de trait voor je eigen type implementeren.
Voorbeeld:
// Extern type en externe trait (niet in onze crate) // struct ExternalType; trait ExternalTrait { ... } struct MyWrapper(ExternalType); impl ExternalTrait for MyWrapper { /* ... */ } // Nu werken we via de wrapper
Vraag: Kun je een externe trait voor een extern type implementeren als beiden openbaar zijn, via use en impl?
Onjuiste antwoord: Ja, het is voldoende om gewoon de impl in je eigen crate te verklaren, en alles zal werken.
Juiste antwoord: Nee, de compiler zal dat niet toestaan. Het is alleen toegestaan om een trait te implementeren als de trait of het type is gedeclareerd in de huidige crate. Anders is er een weesregel fout.
Voorbeeld foutmelding:
// extern crate other; // impl Display for other::ExternalType { ... } // Fout weesregel
Verhaal
Het team had ondersteuning nodig voor een externe logger via impl van een externe trait. Pogingen om deze voor een extern type te implementeren leidde tot een weesregel fout en lange discussies over de oorzaken. Uiteindelijk moest de architectuur worden herontworpen naar newtype.
Verhaal
In een open-source project besloten ze om Debug te implementeren voor een structuur uit een andere bibliotheek, wat niet mogelijk was door de weesregel. Als gevolg hiervan waren gebruikers gedwongen om te werken met onhandige workarounds en hun eigen wrappers te schrijven.
Verhaal
Ernstige bug: bij de poging om FromStr voor een extern enum voor het parseren van een string te implementeren, stond de compiler de weesregel niet toe. De ontwikkelaar "oplosste" het probleem via unsafe geheugenmanipulaties, wat leidde tot UB in productie.