Understanding Go Composite Data Types: Arrays, Slices, Maps, and Structs
This article provides a comprehensive guide to Go's four main composite data types—arrays, slices, maps, and structs—explaining their definitions, initialization, operations, characteristics, and best‑practice recommendations for effective Go programming in software development.
1. Arrays
1.1 Declaration and Initialization
An array is a fixed‑length sequence of elements of the same type. In Go, the length is part of the type, so [5]int and [10]int are different types.
// Declare an array of 5 integers, zero‑initialized
var a [5]int
// Declare and initialize an array
b := [3]int{1, 2, 3}
// Let the compiler infer the length
c := [...]int{1, 2, 3, 4, 5}
// Index‑specific initialization
d := [5]int{1: 10, 3: 30}1.2 Operations
// Access element
first := b[0]
// Modify element
b[1] = 20
// Get length
length := len(b)
// Iterate array
for i, v := range b {
fmt.Printf("Index: %d, Value: %d\n", i, v)
}1.3 Characteristics
Fixed length, cannot change dynamically
Value type; assignment copies the entire array
Memory is contiguous, offering high access efficiency
2. Slices
2.1 Definition and Initialization
A slice provides a flexible, powerful abstraction over arrays; it does not store data itself but references an underlying array.
// Create a slice from an array
arr := [5]int{1, 2, 3, 4, 5}
slice1 := arr[1:4] // elements 2,3,4
// Directly create a slice
slice2 := []int{1, 2, 3}
// Use make to create a slice with length and capacity 5
slice3 := make([]int, 5) // length=capacity=5
slice4 := make([]int, 3, 10) // length=3, capacity=102.2 Operations
// Access and modify element
slice2[0] = 10
// Append elements
slice2 = append(slice2, 4, 5, 6)
// Concatenate slices
slice2 = append(slice2, slice3...)
// Get length and capacity
length := len(slice2)
capacity := cap(slice2)
// Copy slice
slice5 := make([]int, len(slice2))
copy(slice5, slice2)
// Iterate slice
for i, v := range slice2 {
fmt.Printf("Index: %d, Value: %d\n", i, v)
}2.3 Characteristics
Dynamic size; can grow and shrink
Reference type; assignment copies only the slice header (pointer, length, capacity)
Automatically expands when capacity is insufficient
Supports slice operations like s[low:high]
3. Maps
3.1 Definition and Initialization
A map is an unordered collection of key‑value pairs, also known as a dictionary or hash table.
// Declare and initialize
m1 := map[string]int{"apple": 5, "banana": 10}
// Create with make
m2 := make(map[string]float64)
// Declare a nil map
var m3 map[int]string // nil, cannot be used directly3.2 Operations
// Add or modify element
m1["orange"] = 8
// Retrieve element
quantity := m1["apple"]
// Check existence
if q, ok := m1["pear"]; ok {
fmt.Println("pear quantity:", q)
} else {
fmt.Println("pear not found")
}
// Delete element
delete(m1, "banana")
// Iterate map
for k, v := range m1 {
fmt.Printf("Key: %s, Value: %d\n", k, v)
}
// Get map size
size := len(m1)3.3 Characteristics
Keys must be comparable types (cannot be slices, functions, etc.)
Unordered; iteration order is nondeterministic
Reference type; assignment copies only the reference
Zero value is nil; a nil map cannot have elements added
4. Structs
4.1 Definition and Initialization
A struct groups together fields of possibly different types into a single composite type.
// Define struct type
type Person struct {
Name string
Age int
Address string
}
// Initialize structs
p1 := Person{"Alice", 25, "123 Main St"}
p2 := Person{
Name: "Bob",
Age: 30,
Address: "456 Oak Ave",
}
// Create pointer with new
p3 := new(Person)
p3.Name = "Charlie"4.2 Operations
// Access field
name := p1.Name
// Modify field
p1.Age = 26
// Compare structs
if p1 == p2 {
fmt.Println("Same person")
}
// Anonymous struct
temp := struct {
ID int
Desc string
}{
ID: 1,
Desc: "Temporary",
}
// Embedded struct example
type Employee struct {
Person
Position string
Salary float64
}
emp := Employee{
Person: Person{"Dave", 35, "789 Pine Rd"},
Position: "Developer",
Salary: 75000.0,
}4.3 Characteristics
Value type; assignment copies the entire struct
Can have methods, forming the basis of object‑oriented programming
Supports embedding fields for simple inheritance
Fields can have tags for reflection and other purposes
5. Comparing and Choosing Composite Types
Type
Characteristics
Suitable Scenarios
Array
Fixed length, value type
Fixed‑size collections with known length
Slice
Dynamic length, reference type
When a flexible collection is needed
Map
Key‑value pairs, unordered, reference type
Fast lookup of keyed data
Struct
Custom field collection, value type
Representing complex entities or aggregated data
6. Best Practices
Prefer slices unless a fixed length is explicitly required.
Pre‑allocate capacity with make when the approximate size is known to reduce reallocations.
Check map key existence using the two‑value assignment, not by relying on zero values.
Export struct fields with capitalized names to make them public.
Consider using pointer receivers for large structs to avoid copying overhead.
Conclusion
Mastering Go's composite data types is essential for any Go developer. Arrays provide low‑level control, slices are the most commonly used sequence type, maps enable efficient key‑value lookups, and structs let you define custom complex types. Understanding their traits and appropriate use cases leads to better design decisions in Go projects.
php中文网 Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.