#Klooienmetcomputers

Ownership

Arnout van Kempen over rommelen in een digitale wereld.

Rust lijkt op C, gebruikt concepten die ook in andere talen bestaan, maar heeft een paar eigenschappen die echt heel erg typisch Rust zijn. Die hebben te maken met een probleem in C waarover we het eerder hadden: memory leaks en andere problemen met pointers en geheugen.

In C kan bijna alles. Ook als het nergens op slaat. Zo heeft de compiler er geen enkel probleem mee als je met malloc() dynamisch geheugen alloceert en de pointer naar dat geheugen een andere waarde geeft, zonder dat je het geheugen eerst netjes vrij gaf. Dat blok geheugen blijft dan gereserveerd gedurende de looptijd van je programma, maar het is onbereikbaar geworden omdat je geen pointer meer hebt. Bij linked lists zagen we datzelfde verschijnsel: Als je een pointer in de list verkeerd verwijst, verbreek je de list, en wordt alles na die pointer onbereikbaar. Maar wel nog aanwezig in het geheugen. Op diezelfde manier kan je nog veel meer ongelukken laten gebeuren.

Veel talen lossen dat probleem op met een garbage collector. Een stuk programmatuur dat, zonder dat je daar zelf iets voor doet, aan je programma wordt toegevoegd. De garbage collector gaat periodiek na of er geheugen leaks zijn ontstaan en ruimt het zo verspilde geheugen op. Dat is mooi, maar het betekent ook dat je programma steeds onderbroken wordt om de garbage collector aan het werk te zetten. Niet zo handig als je programma snelheid moet maken, of als timing van belang is.

Rust lost dat anders op. Zo op het eerste gezicht kan je in Rust precies hetzelfde doen als in C. Maar als je je programma aan de compiler aanbiedt, toont Rust zijn bijzonderheid: Programma's die de veiligheidsregels van Rust niet in acht nemen, worden simpelweg niet gecompileerd. Rust geeft gelukkig nauwkeurige en heldere foutmeldingen, maar dat neemt niet weg dat je programma wordt geweigerd.
Het levert een interessant verschijnsel op: De compiler van Rust is vrij traag en het is onwaarschijnlijk lastig een programma door de compiler te krijgen. Maar in ruil voor die pijn vooraf, krijg je een programma dat werkt. Niet meestal, niet als je geluk hebt, maar altijd. En zeker zo aardig: Het blijft ook werken. En je programma werkt ook nog eens als de brandweer. Razendsnel. Want geen garbage collector nodig, je programma kan immers simpelweg geen garbage laten ontstaan.

Een van de belangrijkste concepten in Rust om dit doel te bereiken is ownership. (Aangezien de meeste literatuur over Rust in het Engels is, volg ik voor de leesbaarheid de Engelse woorden voor typische Rust-termen, ook al zijn ze prima te vertalen naar Nederlands.)
De basisregels voor ownership zijn op het oog simpel:

  1. Iedere waarde in Rust heeft een owner.
  2. Op ieder moment kan er slechts één owner zijn voor een waarde.
  3. Op het moment dat de owner out of scope gaat, wordt de waarde gedropped.

Daar zit wel een addertje onder het gras: Als de waarde een simpel type heeft, waarvan de compiler weet hoeveel geheugen het nodig heeft, gedraagt Rust zich anders dan bij een type waarvan de compiler niet kan weten hoeveel geheugen het nodig heeft.
De scope van een variabele loopt vanaf het moment dat de variabele wordt gedeclareerd, tot het einde van het codeblock waarbinnen dat is gebeurd.
Hoe ziet dat er nu uit bij een type waarvan het geheugenbeslag onbekend is op het moment van compileren? Neem het type String (en vergeet even de onbekende syntax voor dit moment).

{
     let mut vbs = String::from(“voorbeeld “); // in scope
     vbs.push_str(“van een string”);
     println!(“{}”,vbs); // out of scope
}

zal voorbeeld van een string op het scherm zetten. De mutable variabele vbs krijg eerst een inhoud, die vervolgens wordt aangevuld. De lengte varieert dus, en daarmee ook het geheugenbeslag.

De variabele vbs wordt in scope gebracht met de let mut vbs =… opdracht. Dat ligt voor de hand. Maar iets minder voor de hand liggend is wat op het einde van het codeblock gebeurt: vbs gaat out of scope en de waarde van vbs wordt automatisch gedropped. Na de laatste } bestaat vbs dus niet meer en de inhoud of waarde van vbs evenmin.

Is dat nou ingewikkeld? Niet echt. Maar het wordt ingewikkelder als we waarden gaan verplaatsen, als we simpele en complexe typen gaan gebruiken en als we waarden gaan uitlenen.

Wie mee wil doen met #klooienmetcomputers kan dat doen via GitHub. Maak een account op www.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.