Opnieuw traits
Arnout van Kempen over rommelen in een digitale wereld.
Iets wat mij niet lukte de vorige keer, is het schrijven van een trait die werkt op types die gebruikmaken van een andere trait en dan ook gebruikmaken van die trait. Klinkt raadselachtig? Is het toch niet: Ik had drie structs, Vierkant, Cirkel, Driehoek met ieder de trait OppervlakteBerekening. Voor iedere figuur is de berekening van de oppervlakte verschillend, dus je wil per struct een eigen methode, met impl, die zorgt voor de berekening.
Maar als je vervolgens een trait wil die de inhoud berekent van een figuur die je uit een plank zaagt, dan zou dat voor ieder figuur hetzelfde moeten zijn: oppervlakte van de figuur * dikte van de plank. En dus wil je één trait, generiek, die je ook maar één keer definieert, en niet iedere keer hetzelfde per figuur-struct.
Het lukte mij niet. Uit alles wat ik las, stond voor mij wel vast dat het moest kunnen. Met generieke definities zoals we eerder zagen met generieke functies? Zou moeten kunnen, maar werkte niet. Via het Rust-forum begreep ik wel een deel van het probleem. Als je de inhoud-trait maakt en je gebruikt de oppervlakte-trait, moet de compiler wel weten dat die oppervlakte-trait is gedefinieerd voor het figuur dat je wil gebruiken. Dus dat moet je op een of andere manier aangeven. Maar ik kon niet vinden hoe.
Voordeel daarvan: Ik moest wel een functie gebruiken. Zie de code van vorige keer, waar inderdaad een functie in zit om de inhoud te berekenen op basis van de oppervlakte-trait. Best mooi. Maar niet perfect. Dus ik uitte mijn frustraties op LinkedIn. En zie daar de kracht van sociale media. Binnen een uurtje of wat kwam een reactie van Perry van der Meer, IT-dataspecialist bij Confirm, die via GitHub mijn code had aangepast om te laten zien hoe het wel moest. Daarmee meteen iets anders moois illustrerend van computerklojo's: De grote bereidheid elkaar te helpen, onder andere (vermoed ik) omdat we allemaal wel eens op het punt stonden onze computer uit het raam te donderen.
Wat is nu de oplossing? Je moet inderdaad een generieke trait maken en die vertellen dat deze gebruik wil maken van de oppervlakte-trait. En wel zo:
trait InhoudBerekening: OppervlakteBerekening {
fn inhoud(&self, hoogte: f64) -> f64 {
self.oppervlakte() * hoogte
}
}
En vervolgens per soort figuur (hier alleen voor het Vierkant):
impl InhoudBerekening for Vierkant {}
Je kan nu in je code simpelweg vierkant.inhoud(plank_dikte) gebruiken voor de inhoud van een vierkant stukje plank.
Ook deze code staat weer op GitHub, dus leef je uit!
Wie mee wil doen met #klooienmetcomputers kan dat doen via GitHub. Maak een account op github.com en zoek naar Abmvk/kmc. Het account Abmvk volgen kan ook. Lezers zijn vrij te gebruiken wat ze willen en om zelf zaken toe te voegen of aan te passen, vragen te stellen of commentaar te leveren.
Gerelateerd
Van 4004 naar 86-64
Arnout van Kempen over rommelen in een digitale wereld.
We gaan diep!
Arnout van Kempen over rommelen in een digitale wereld.
Herhalingen
Arnout van Kempen over rommelen in een digitale wereld.
Voorwaarden in COBOL
Arnout van Kempen over rommelen in een digitale wereld.
Het Y2K-probleem
Arnout van Kempen over rommelen in een digitale wereld.