3 min read

Maps in Go with Tests

Table of Contents

Hey there! 👋 Ready to dive into Go maps? Think of them like a real-world dictionary - but way more fun (and with less paper cuts).

Let’s break it down!

What’s a Map, Anyway? 🤔

Imagine your fridge is a map:

  • Keys = Food names (“pizza”, “salad”)
  • Values = Descriptions (“delicious”, “what mom makes you eat”)

In Go, we’d write that as map[string]string - keys and values are both strings.

Let’s Build a Dictionary! 📖

First Test: The Search Party 🔍

func TestSearch(t *testing.T) {
    dictionary := map[string]string{"cookie": "yummy baked good"}

    got := Search(dictionary, "cookie")
    want := "yummy baked good"

    if got != want {
        t.Errorf("Got %q but wanted %q - my sweet tooth is disappointed!", got, want)
    }
}

Making It Work 🛠️

func Search(dictionary map[string]string, word string) string {
    return dictionary[word] // Easy peasy!
}

Pro tip: Maps return two values - the value and a boolean if the key exists.

Super useful for error handling!

Level Up: Custom Dictionary Type 🎚️

type Dictionary map[string]string

func (d Dictionary) Search(word string) (string, error) {
    definition, ok := d[word]
    if !ok {
        return "", errors.New("Word not found - time to hit the books!")
    }
    return definition, nil
}

Adding New Words ➕

func TestAdd(t *testing.T) {
    dictionary := Dictionary{}
    dictionary.Add("programmer", "magic coffee-powered creature")

    got, _ := dictionary.Search("programmer")
    want := "magic coffee-powered creature"

    if got != want {
        t.Errorf("Definition mismatch! Got %q want %q", got, want)
    }
}

Implementation:

func (d Dictionary) Add(word, definition string) error {
    _, err := d.Search(word)

    switch err {
    case ErrNotFound:
        d[word] = definition // Add new word
    case nil:
        return ErrWordExists // Word already there!
    default:
        return err // Other errors
    }
    return nil
}

Updating Definitions 🔄

Because even dictionaries need updates (looking at you, “literally”):

func (d Dictionary) Update(word, definition string) error {
    _, err := d.Search(word)

    switch err {
    case ErrNotFound:
        return ErrWordDoesNotExist // Can't update what's not there!
    case nil:
        d[word] = definition // Update away!
    default:
        return err
    }
    return nil
}

When Words Go Bad ❌

Time to delete some words (looking at you, “moist”):

func (d Dictionary) Delete(word string) error {
    _, err := d.Search(word)

    switch err {
    case ErrNotFound:
        return ErrWordDoesNotExist
    case nil:
        delete(d, word) // Built-in delete function!
    default:
        return err
    }
    return nil
}

Key Takeaways 🗝️

  • Maps are like real dictionaries (but faster than flipping pages)
  • They store key-value pairs
  • Can check if key exists with the two-value return
  • Built-in delete function removes entries
  • Custom types make your code cleaner
  • Error handling makes your code robust

Next Up: dependency injection

Support my open source work 🚀

Let's Connect

I'm open to discussing new opportunities. Feel free to connect with me or send me an email at [email protected]