Introduction to Maps
A map is an unordered collection of key-value pairs. Each key is unique within a map, and the keys are used to look up values associated with them. Maps provide efficient lookups, additions, and deletions.
Creating and Initializing Maps
-
Creating a Map Using
make
: You can create a map using themake
function, specifying the key and value types.var m map[string]int m = make(map[string]int)
-
Creating and Initializing a Map Using a Composite Literal: You can also create and initialize a map using a composite literal.
m := map[string]int{ "apple": 1, "banana": 2, }
Adding and Updating Elements
You can add or update elements in a map by assigning a value to a key.
m["orange"] = 3
m["apple"] = 4 // Updating the value for the key "apple"
Accessing Elements
You can access elements in a map using the key.
appleCount := m["apple"]
fmt.Println("Apple count:", appleCount)
Deleting Elements
You can delete elements from a map using the delete
function.
delete(m, "banana")
Checking if a Key Exists
You can check if a key exists in a map using the value and ok
idiom.
val, ok := m["banana"]
if ok {
fmt.Println("Banana count:", val)
} else {
fmt.Println("Banana does not exist")
}
Iterating Over a Map
You can iterate over a map using a for
loop with the range
keyword.
for key, value := range m {
fmt.Println("Key:", key, "Value:", value)
}
Map with Struct Values
Maps can hold values of any type, including structs.
type Person struct {
Name string
Age int
}
people := map[string]Person{
"John": {Name: "John Doe", Age: 30},
"Jane": {Name: "Jane Smith", Age: 25},
}
Example: Comprehensive Map Usage
Here is a complete example demonstrating various operations with maps:
package main
import (
"fmt"
)
func main() {
// Creating and initializing a map
fruits := map[string]int{
"apple": 5,
"banana": 3,
"orange": 4,
}
// Adding and updating elements
fruits["grape"] = 7
fruits["apple"] = 10
// Accessing elements
fmt.Println("Apple count:", fruits["apple"])
// Checking if a key exists
val, ok := fruits["banana"]
if ok {
fmt.Println("Banana count:", val)
} else {
fmt.Println("Banana does not exist")
}
// Deleting elements
delete(fruits, "orange")
// Iterating over a map
for key, value := range fruits {
fmt.Println("Key:", key, "Value:", value)
}
// Map with struct values
type Person struct {
Name string
Age int
}
people := map[string]Person{
"John": {Name: "John Doe", Age: 30},
"Jane": {Name: "Jane Smith", Age: 25},
}
for username, person := range people {
fmt.Printf("Username: %s, Name: %s, Age: %d\n", username, person.Name, person.Age)
}
}
Key Points
- Unordered: Maps do not maintain any order for keys and values.
- Efficient Lookups: Maps provide efficient key lookups and are ideal for scenarios where you need quick data retrieval.
- Zero Values: If a key does not exist in the map, accessing it returns the zero value for the map’s value type.
- Concurrency: Maps are not safe for concurrent use. If you need to use a map across multiple goroutines, you must use synchronization mechanisms like
sync.Mutex
.