rust 37 lines · 6 steps

A generic memoizer in Rust

A reusable struct that caches the results of any pure function, keyed by its input.

Explained by highlit
1use std::collections::HashMap;
2 
3pub struct Memoizer<K, V, F> {
4 cache: HashMap<K, V>,
5 compute: F,
6}
7 
8impl<K, V, F> Memoizer<K, V, F>
9where
10 K: std::hash::Hash + Eq + Clone,
11 V: Clone,
12 F: Fn(&K) -> V,
13{
14 pub fn new(compute: F) -> Self {
15 Self {
16 cache: HashMap::new(),
17 compute,
18 }
19 }
20 
21 pub fn get(&mut self, key: K) -> V {
22 if let Some(value) = self.cache.get(&key) {
23 return value.clone();
24 }
25 let value = (self.compute)(&key);
26 self.cache.insert(key, value.clone());
27 value
28 }
29 
30 pub fn len(&self) -> usize {
31 self.cache.len()
32 }
33 
34 pub fn invalidate(&mut self, key: &K) -> Option<V> {
35 self.cache.remove(key)
36 }
37}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Storing a closure in a generic field lets one struct memoize any compatible function.
  2. 2Trait bounds like Hash, Eq, and Clone express exactly what the cache needs from its types.
  3. 3Checking the cache before computing turns repeated work into a single hash lookup.

Related explainers

Share this explainer

Here's the card — post it anywhere.

A generic memoizer in Rust — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code