Data Structures
Although Go has simple syntax, it has many powerful built-in core data structures. These data structures are the basic building blocks of Go programs. Understanding their implementation principles helps write more efficient code. This article introduces several commonly used data structures in Go and their underlying implementations.
Basic Data Structures
slice
Slice is the most commonly used data structure in Go, an abstraction and wrapper of arrays. Main features:
- Dynamic size: Slice length can grow dynamically
- Reference semantics: Only the struct is copied when passing slices, not the underlying array
- Expansion mechanism: Automatically expands when capacity is insufficient
At runtime, slices are represented by the slice struct, containing three fields: pointer to the underlying array, length, and capacity.
string
String is one of the most basic data types in Go. Main features:
- Immutability: Once created, strings cannot be modified
- UTF-8 encoding: Usually represents UTF-8 encoded text
- Zero value safety: The zero value of string is empty string
"", notnil
At runtime, strings are represented by the stringStruct struct, containing a pointer to a byte array and length.
Container Data Structures
map
map is Go's built-in key-value container, implemented using a hash table. Main features:
- Hash table implementation: Quickly locate elements using hash functions
- Automatic expansion: Automatically expands when load factor is too high
- Not concurrency safe: Concurrent read/write requires additional synchronization
At runtime, maps are represented by the hmap struct, containing bucket array, hash seed, element count, and other fields.
syncmap
sync.Map is a concurrency-safe map provided by the standard library, suitable for read-mostly scenarios. Main features:
- Read-write separation: Uses two maps, read and dirty, for read-write separation
- Atomic operations: read map uses atomic operations without locking
- Progressive migration: Promotes dirty to read when miss count reaches threshold
sync.Map trades space for time, providing better performance than map + mutex in specific scenarios.
Concurrency Data Structures
channel
channel is a typical representative of Go's CSP philosophy, used for communication between goroutines. Main features:
- Goroutine communication: Passes data between goroutines through channel
- Synchronization mechanism: Unbuffered channel can be used for goroutine synchronization
- Locked queue: Underlying is a locked circular queue
At runtime, channels are represented by the hchan struct, containing circular buffer, wait queue, and other fields.
select
select can monitor the state of multiple channels simultaneously, achieving multiplexing. Main features:
- Non-blocking: Can non-blockingly check if multiple channels are available
- Random selection: Randomly selects one case when multiple channels are available
- Timeout control: Can implement timeout mechanism with
time.After
At runtime, select uses the scase struct to represent each branch, checking channel states through polling.
Learning Suggestions
Recommended learning order:
- First learn slice and string to understand basic data structures
- Then learn map to understand hash table implementation
- Then learn channel to understand goroutine communication mechanism
- Then learn select to master multiplexing techniques
- Finally learn syncmap to understand concurrency-safe implementation
