#Klooienmetcomputers

Structuur met methodes

Arnout van Kempen over rommelen in een digitale wereld.

We zagen eerder dat Rust het datatype "tuple" kent. Handig om data te structureren, maar het is te beperkt als het daarbij blijft. We willen structs, enums, arrays. En dat hebben we. Allemaal erg vergelijkbaar met C. Maar Rust biedt iets dat we uit C niet kennen: een functie die in een data-type zit opgeborgen, een method. C++ en Python kennen dit ook, maar dan zit de method in een class.

Op GitHub staat een, overigens vrij nutteloos en overgecompliceerd, programma om dat zichtbaar te maken. Het programma slaat de namen op van de bewoners van woning 2 in een wooncomplex: Henk, Mary, Poekie en Bello.

Om te beginnen introduceert het de enum, hiermee kunnen we een type maken met een gegeven aantal mogelijke waarden. Hier is het

enum Soort {
     Mens,
     Hond,
     Kat,
}

En die waarden kunnen hierna worden aangeroepen als Soort::Mens, etcetera. Die :: zagen we al eerder en zullen we nog vaak zien in Rust, als teken dat we "iets" uit "iets anders" gebruiken.

Na de enum volgt een struct:

struct Bewoner {
     mens: bool,
     naam: String,
     woning: u32,
     soort: Soort,
}

Nog steeds niets geks, als we C kennen. Maar nu volgt de methode. Dat is in feite een functie, die we ook schrijven als een functie-definitie; maar deze is gekoppeld aan een type en wel een struct. Dat betekent dat de methode pas betekenis krijgt als we een variabele van dat type definiëren. Maar dan werkt de methode ook op iedere variabele van dat type. Ongemerkt zijn we dat idee al eerder tegengekomen met types die standaard zijn in Rust, bijvoorbeeld met &str en String. Maar nu kunnen we het dus zelf ook.

Is dat nou handig? Laten we niet overdrijven: ook zonder methods kom je een heel eind. C kent het systeem niet en daar konden we ook doen wat we wilden. Maar het gebruik van methods staat wel efficiënter en vooral overzichtelijker programmeren toe. Dat blijkt al uit de methode die nu volgt:

impl Bewoner {
     fn voeren(&self) -> bool {
          !self.mens
     }
}

Met de eerste regel geven we aan dat een methode voor het type Bewoner volgt. En met &self verwijzen we naar de elementen van de struct waarop de methode toegepast gaat worden. We hadden vanzelfsprekend ook een gewone functie kunnen maken, met als argument een variabele van het type Bewoner en als resultaat een bool. Het punt is alleen dat door er een methode van te maken, net iets duidelijker is waar de functie fn voeren() op slaat. We willen niet zomaar iets weten over “voeren”, we willen weten of we een bewoner moeten voeren.

Na al deze definities volgt fn main() waarin we eerst een mutable array van vier bewoners declareren en vullen. bewoner[0] vullen we meteen met de gegevens van Henk. Dat is een manier om een struct van waarden te voorzien. Het kan ook na de declaratie, zoals we zien bij bewoner[1], ofwel Marie. En we kunnen een struct ook vullen in een functie. Dat zien we in de functie:

fn nieuwe_kat(naam: String, woning: u32) -> Bewoner {
     Bewoner {
          mens: false,
          naam,
          woning,
          soort: Soort::Kat,
     }
}

Merk op dat we als argumenten dezelfde namen gebruiken als de velden in de struct en daardoor hoeven we niet zoiets te doen als naam: Bewoner.naam; maar we zetten simpelweg de argumenten van de functie in de struct. En gegevens die wel moeten worden ingevuld, vullen we in.

Als laatste wordt Bello toegevoegd, als kat, om daarna alleen de soort te veranderen in Hond.Tenslotte doen we een

for bewoner in &bewoner { 

om alle elementen van de array bewoner na te lopen. Per bewoner printen we de naam en het nummer van de woning. En als het om huisdieren gaat, voegen we toe dat die wel gevoerd moeten worden.

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.

Arnout van Kempen di CCO CISA is Senior manager Risk & Compliance bij Baker Tilly. Hij schrijft op persoonlijke titel. Hij is lid van de Commissie Financiƫle verslaggeving & Accountancy van de AFM en lid van de signaleringsraad van de NBA. Daarnaast is hij diaken van het bisdom 's-Hertogenbosch.

Gerelateerd

reacties

Reageer op dit artikel

Spelregels debat

    Aanmelden nieuwsbrief

    Ontvang elke werkdag (maandag t/m vrijdag) de laatste nieuwsberichten, opinies en artikelen in uw mailbox.

    Bent u NBA-lid? Dan kunt u zich ook aanmelden via uw ledenprofiel op MijnNBA.nl.