Mengen in Go 1.21: Eine ausführliche Anleitung
Sets in Go 1.21
What is a set and why do you need it?
Imagine you have a box where you can only put unique items. If you try to put two identical apples in it, only one will remain in the box. This is a set — a collection where each element occurs only once.
Why is this needed? For example:
- Check if a product is in the store
- Remove duplicate ingredients from a recipe
- Merge guest lists without duplicates
Go 1.21 doesn't have a built-in "set" type, but we can easily create one using map!
How to create a set in Go?
We will use map[string]struct{}. Why struct{}? Because it's an empty struct that takes up no memory — perfect for storing only keys!
// Create an empty set
contacts := make(map[string]struct{})
// Add elements
contacts["Anna"] = struct{}{}
contacts["Boris"] = struct{}{}
contacts["Anna"] = struct{}{} // Duplicate — nothing changes
// Check if an element exists
if _, exists := contacts["Anna"]; exists {
fmt.Println("Anna is in contacts!")
}
// Delete an element
delete(contacts, "Boris")
// Number of elements
fmt.Println(len(contacts)) // Output: 1
Basic set operations
1. Creating and adding elements
package main
import "fmt"
func main() {
// Create a set for pizza ingredients
ingredients := make(map[string]struct{})
// Add ingredients
ingredients["cheese"] = struct{}{}
ingredients["tomatoes"] = struct{}{}
ingredients["cheese"] = struct{}{} // Duplicate won't be added
fmt.Println("Ingredients:", ingredients) // map[cheese:{} tomatoes:{}]
fmt.Println("Count:", len(ingredients)) // 2
}
2. Checking if an element exists
package main
import "fmt"
func main() {
products := map[string]struct{}{
"milk": {},
"bread": {},
"eggs": {},
}
var item string
fmt.Print("Enter product to check: ")
fmt.Scan(&item)
if _, exists := products[item]; exists {
fmt.Println("Product is in stock!")
} else {
fmt.Println("Product is not in stock.")
}
}
3. Deleting elements
package main
import "fmt"
func main() {
shoppingList := map[string]struct{}{
"milk": {},
"bread": {},
"eggs": {},
"cheese": {},
}
fmt.Println("Shopping list:", shoppingList)
// Delete an unwanted item
delete(shoppingList, "milk")
fmt.Println("After deletion:", shoppingList)
}
4. Merging sets
package main
import "fmt"
func main() {
// Host's shopping list
hostList := map[string]struct{}{
"juice": {},
"chips": {},
"pizza": {},
}
// What guests suggested
guestList := map[string]struct{}{
"juice": {},
"cake": {},
"lemonade": {},
}
// Merge — add everything from guestList to hostList
for item := range guestList {
hostList[item] = struct{}{}
}
fmt.Println("Final shopping list:")
for item := range hostList {
fmt.Println("-", item)
}
}
Typical problem walkthroughs
Problem: Pizza ingredients (unique)
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Print("Enter ingredients separated by commas: ")
var input string
fmt.Scan(&input)
// Split the string into parts
items := strings.Split(input, ",")
// Create a set for unique ingredients
uniqueIngredients := make(map[string]struct{})
for _, item := range items {
// Remove extra spaces and add
cleanItem := strings.TrimSpace(item)
if cleanItem != "" {
uniqueIngredients[cleanItem] = struct{}{}
}
}
fmt.Println("Unique ingredients:")
for ingredient := range uniqueIngredients {
fmt.Println("-", ingredient)
}
}
Input: cheese, tomatoes, cheese, mushrooms, tomatoes
Output: cheese, tomatoes, mushrooms
Problem: Finding missing products
package main
import "fmt"
func main() {
// Products that should always be in stock
required := map[string]struct{}{
"milk": {},
"bread": {},
"eggs": {},
"cheese": {},
}
// Ask what is available
fmt.Println("What products are available? (enter one by one, 'stop' to finish)")
available := make(map[string]struct{})
for {
var item string
fmt.Print("Product: ")
fmt.Scan(&item)
if item == "stop" {
break
}
available[item] = struct{}{}
}
// Find what is missing
fmt.Println("Need to buy:")
for item := range required {
if _, exists := available[item]; !exists {
fmt.Println("-", item)
}
}
}
Common beginner mistakes
- Forgetting to check if an element exists — always use
if _, exists := set[key]; exists { ... } - Trying to get a value by key — a set has no values, only keys. Use existence check.
- Confusing map[string]bool and map[string]struct{} —
struct{}{}takes 0 bytes, whilebooltakes 1 byte. For sets,struct{}{}is better. - Not trimming spaces — when entering via comma, spaces remain. Always use
strings.TrimSpace().
Final example: Contact notebook
package main