Module: Data Structures

Arrays

Go Programming: Data Structures - Arrays

Arrays are fundamental data structures in Go, used to store a fixed-size sequential collection of elements of the same type. Here's a comprehensive overview:

1. What is an Array?

  • Definition: An array is a contiguous block of memory locations, each holding an element of the same data type.
  • Fixed Size: The size of an array is determined at the time of declaration and cannot be changed later. This is a key difference between arrays and slices (which we'll cover later).
  • Homogeneous: All elements within an array must be of the same type (e.g., all integers, all strings, all booleans).
  • Zero-Based Indexing: Array elements are accessed using indices starting from 0.

2. Declaring Arrays

There are several ways to declare arrays in Go:

a) Explicit Size:

var arr [5]int // Declares an array of 5 integers, initialized to zero values

b) Initialization with Values:

arr := [5]int{1, 2, 3, 4, 5} // Declares and initializes an array of 5 integers

c) Size Inference (using ...):

arr := [...]int{1, 2, 3, 4, 5} // The compiler infers the size (5) from the initializer list

d) Multi-dimensional Arrays:

var matrix [3][3]int // A 3x3 matrix of integers
matrix := [3][3]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}} // Initializing a 3x3 matrix

Explanation:

  • var arr [5]int: This declares a variable named arr as an array that can hold 5 integers. The elements are automatically initialized to the zero value for integers (which is 0).
  • arr := [5]int{1, 2, 3, 4, 5}: This declares and initializes an array named arr with the specified values.
  • arr := [...]int{1, 2, 3, 4, 5}: The ... tells the compiler to determine the array's size based on the number of elements in the initializer list.
  • [3][3]int: This represents a two-dimensional array (a matrix) with 3 rows and 3 columns, each element being an integer.

3. Accessing Array Elements

Array elements are accessed using their index within square brackets [].

arr := [5]int{10, 20, 30, 40, 50}

fmt.Println(arr[0]) // Output: 10 (first element)
fmt.Println(arr[2]) // Output: 30 (third element)

// Modifying an element
arr[1] = 25
fmt.Println(arr[1]) // Output: 25

Important:

  • Accessing an index outside the array's bounds will cause a runtime panic (an error that crashes the program). Go does not perform bounds checking at compile time for arrays.

4. Array Length

The len() function returns the length (number of elements) of an array.

arr := [5]int{1, 2, 3, 4, 5}
length := len(arr)
fmt.Println(length) // Output: 5

5. Iterating Through Arrays

You can use a for loop to iterate through the elements of an array.

a) Using Index:

arr := [5]int{1, 2, 3, 4, 5}
for i := 0; i < len(arr); i++ {
    fmt.Println(arr[i])
}

b) Using range:

arr := [5]int{1, 2, 3, 4, 5}
for index, value := range arr {
    fmt.Printf("Index: %d, Value: %d\n", index, value)
}

The range keyword provides both the index and the value for each element in the array.

6. Arrays as Function Parameters

When passing an array to a function, you are passing a copy of the array. This means that any modifications made to the array within the function will not affect the original array.

func modifyArray(arr [5]int) {
    arr[0] = 100
}

func main() {
    arr := [5]int{1, 2, 3, 4, 5}
    modifyArray(arr)
    fmt.Println(arr) // Output: [1 2 3 4 5] (original array is unchanged)
}

7. Arrays vs. Slices

Arrays and slices are often confused, but they are different:

Feature Array Slice
Size Fixed at declaration Dynamic (can grow or shrink)
Mutability Elements can be modified, but size cannot Elements can be modified, and size can be changed
Passing to Functions Passed by value (copy) Reference to underlying array (changes affect original)
Declaration [size]type []type

Slices are generally preferred over arrays in Go because of their flexibility. Slices are built on top of arrays, providing a more convenient and powerful way to work with sequences of data.

8. Example: Finding the Sum of Array Elements

package main

import "fmt"

func main() {
    numbers := [5]int{1, 2, 3, 4, 5}
    sum := 0

    for _, num := range numbers {
        sum += num
    }

    fmt.Println("Sum of array elements:", sum) // Output: Sum of array elements: 15
}

9. When to Use Arrays

While slices are more common, arrays can be useful in specific scenarios:

  • Fixed-size data: When you know the exact size of the data collection at compile time and it won't change.
  • Performance-critical code: Arrays can sometimes offer slightly better performance than slices in certain situations because of their fixed size and direct memory access.
  • Interoperability with C: Arrays are more directly compatible with C code.

This provides a solid foundation for understanding arrays in Go. Remember to consider the limitations of fixed size and explore slices for more flexible data handling.