A cache is, at its heart, a lookup table you can put things into and get things back out of. Today you build that bare contract over a plain map, so the rest of the project has something concrete to make fast and to bound.
Build a cache that stores a value under a key and returns it, reporting whether the key was present.
Every cache is a lookup table with a story about what to throw away. Before any of
the throwing-away, it has to do the plain thing: store a value under a key and
give it back when asked. We will call the type LRU because that is where it
is heading, but today it is just a map with two methods.
The one detail worth pinning now is the shape of Get: it returns the value and
a boolean saying whether the key was there. A cache miss (found = false) is a
first-class outcome, not an error and not a zero value pretending to be data - the
caller needs to know the difference between “the value is 0” and “there is no
value.” Keys and values are int here so every result is a number you can assert;
making the cache generic over any key and value type is a later refinement.
// one map is the whole cache for now; capacity comes next lessontype LRU struct {cap intdata map[int]int}func NewLRU(cap int) *LRU { return &LRU{cap: cap, data: map[int]int{}} }func (c *LRU) Put(key, val int) { c.data[key] = val }func (c *LRU) Get(key int) (int, bool) { v, ok := c.data[key]; return v, ok }