HashMaps
Arnout van Kempen over rommelen in een digitale wereld.
We moeten nog een paar gegevensstructuren in Rust bekijken. Een betrekkelijk simpele is de vector, of vec. Dit is in feite niets anders dan een array, maar dan een array die langer en korter kan worden tijdens het gebruik. Je maakt een vec heel simpel met de macro vec!.
Waar een vec de mogelijkheid toevoegt de lengte van een array te variëren, levert een HashMap een ander, interessant concept op. Bij een array zit je altijd vast aan een index bestaande uit een oplopende reeks cijfers, vanaf 0. Maar soms wil je dat niet. Je zou een array willen waarbij de index gevormd wordt door een code die je zelf kan bepalen. Bijvoorbeeld een tekst, of een numerieke code die niet van 0 tot het einde loopt, of wat dan ook. De oplossing hiervoor is de HashMap. Deze heeft steeds twee waarden tussen haakjes: een sleutelveld en een inhoud- of waarde-veld.
Op GitHub staat een programmaatje dat het gebruik van HashMaps demonstreert. Omdat HashMaps niet altijd worden gebruikt, moet eerst worden aangegeven dat we daarvan wel gebruik willen gaan maken met
use std::collections::HashMap;
En omdat we meteen maar een HashMap van enums gaan maken, definiëren we vervolgens de enum. Maar om dat goed te laten gaan, moeten we aangeven dat de navolgende enum hashable moet worden gemaakt. En om later eenvoudig de inhoud te kunnen printen, moet het ook nog een debugable code zijn. Dit bereiken we door toe te voegen
#[derive(debug, PartialEq, Eq, Hash)]
Meteen daarna definiëren we de enum, in dit geval met seizoenen:
enum Seizoen {
Lente,
Zomer,
Herfst,
Winter,
Onbekend,
}
in de main() functie is het aanmaken van een HashMap vrij eenvoudig:
let mut seizoenen = HashMap::new();
Ik maak er meteen nog een, om te laten zien hoe je ook vec's in een HashMap kan opnemen. Daarvoor verwijs ik verder naar GitHub.
De HashMaps zijn mutable, omdat we er anders vrij weinig mee kunnen. Het idee is immers dat we data gaan toevoegen.
De seizoenen worden gevuld met
seizoenen.insert(String::from(“seizoen1”), Seizoen::Lente);
de insert(key, value) is een methode van de HashMap waarmee een veld wordt toegevoegd. Bij de eerste keer dat je dit doet, weet de compiler wat het type van zowel de key, als de value moet zijn. Vanaf nu zal de compiler vereisen dat alle volgende velden van dezelfde types gebruik maken. In dit geval is de key dus een String en de value een enum Seizoen.
Als je een waarde uit een HashMap wil halen op basis van een key, dan doe je dat met .get(), zie de code op GitHub.
Voeg je met .insert() een veld toe met een al bestaande key, dan zal dat veld overschreven worden. Dat is natuurlijk niet altijd de bedoeling en daarom kan je gebruik maken van een tweetal andere methodes. De ene om te bekijken of een bepaalde key al bestaat en de andere om alleen een value toe te voegen als de gezochte key nog niet bestaat. Dat ziet er dan als volgt uit:
seizoenen
.entry(String::from(“de gezochte key”)
.or_insert(toe_te_voegen_waarde);
De code op GitHub laat zien dat dit inderdaad werkt zoals verwacht.
Omdat we nu niet bezig zijn met heel nette programma’s, gebruiken we een trucje om snel waarden van variabelen te printen. Door de aanduiding {:?} te gebruiken, vraag je aan Rust om een gegevensstructuur in totaliteit te printen, alleen voor debug-doeleinden.
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
Gewone variabelen
Arnout van Kempen over rommelen in een digitale wereld.
Bestanden in soorten en maten
Arnout van Kempen over rommelen in een digitale wereld.
Alles draait om data
Arnout van Kempen over rommelen in een digitale wereld.
Omgeving: input-output
Arnout van Kempen over rommelen in een digitale wereld.
Omgeving: de configuratie
Arnout van Kempen over rommelen in een digitale wereld.