Map — dynamic key-value store with O(1) average lookups, runtime-checked keys. Struct — fixed set of named, typed fields, compile-time checked.
Maps are ideal when keys aren't known at compile time. They use hash tables internally and grow dynamically. Maps are reference types — passing one to a function shares the same data. They are not safe for concurrent writes without synchronization.
1wordCount := make(map[string]int)2for _, w := range words {3 wordCount[w]++4}5if count, ok := wordCount["hello"]; ok {6 fmt.Println("found", count, "times")7}
Structs define a fixed schema at compile time. The compiler catches type errors, IDEs provide autocompletion, and the memory layout is deterministic. Structs compose via embedding for reuse.
1type WordStats struct {2 WordCount map[string]int3 Total int4}
When to use:
Common mistakes:
map[string]interface{} for complex structures — lose type safety and discoverability.ok value — zero values may mask missing data.sync.Map — runtime panic.