Sling Academy
Home/Golang/Understanding Maps with Custom Types as Keys in Go

Understanding Maps with Custom Types as Keys in Go

Last updated: November 24, 2024

In the Go programming language, a map is a built-in data type that stores key-value pairs. Maps are incredibly useful for storing data where you want to define some keys and retrieve corresponding values. However, there can be scenarios where you want to use custom types as keys in a map. Understanding how to effectively use custom types as keys is crucial for robust Go programming.

Introduction to Maps in Go

Before diving into custom keys, let's review the basics of maps in Go. Here's how you create and use a map with simple data types:

package main

import "fmt"

func main() {
    // Creating a map
    capitals := map[string]string{
        "France":    "Paris",
        "Italy":     "Rome",
        "Japan":     "Tokyo",
    }

    // Accessing an element
    capitalOfFrance := capitals["France"]
    fmt.Println("The capital of France is:", capitalOfFrance)

    // Adding an element
    capitals["India"] = "New Delhi"

    // Deleting an element
    delete(capitals, "France")

    // Iterating over a map
    for country, capital := range capitals {
        fmt.Printf("Capital of %s is %s\n", country, capital)
    }
}

Using Custom Types as Map Keys

In Go, the keys of a map must be a type that is comparable with the equality operator, and this includes all primitive types, pointers, and structs (with comparable fields). Here's an example of using a simple struct as a map key:

package main

import "fmt"

type Location struct {
    Latitude  float64
    Longitude float64
}

func main() {
    // Creating a map with a custom struct as the key
    landmarks := make(map[Location]string)

    landmarks[Location{40.748817, -73.985428}] = "Empire State Building"
    landmarks[Location{48.8583701, 2.2944813}] = "Eiffel Tower"

    // Access and display a landmark
    eiffelLocation := Location{48.8583701, 2.2944813}
    fmt.Println("Landmark at Eiffel Location is:", landmarks[eiffelLocation])
}

Complex Custom Key Structures

When using more complex custom types as keys, ensure all fields within the structure have types that can be compared using ==. Here’s an advanced example using a struct with a nested struct:

package main

import "fmt"

type Coordinates struct {
    Lat, Long float64
}

type Place struct {
    Name string
    Coords Coordinates
}

func main() {
    // Create map with structs having nested struct as keys
    worldWonders := make(map[Place]string)

    p1 := Place{"Great Wall of China", Coordinates{40.43208, 116.570375}}
    p2 := Place{"Machu Picchu", Coordinates{-13.163068, -72.545128}}

    worldWonders[p1] = "China"
    worldWonders[p2] = "Peru"

    // Accessing map entries with nested struct
    location := worldWonders[p1]
    fmt.Println("The Great Wall of China is in", location)
}

Considerations for Using Structs as Keys

  • Ensure that all fields of the struct type are also comparable types.
  • Understand that map keys in Go are treated as value-types, meaning if they are structs, the entire key is copied for the map operation.
  • Avoid using maps with keys that have mutable fields, as any changes to these fields will result in a mismatch when accessing the map entry.

By using custom types, you can leverage Go maps for more complex data storage solutions, allowing for clean and efficient code that clearly represents the relationships between your data entities.

Next Article: Creating and Using Read-Only Maps in Go

Previous Article: How to Sort Keys in Go Maps

Series: Working with Maps in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant