hkucuk

Differences Between Array and Slice in GoLang

October 9, 2021 • ☕️ 3 min read • 🏷 computer, software

Translated by author into: English


Array

The Array data type is a fixed-length data structure in which an array of elements is of the same data type. When defining arrays, the number of elements and the data type of each element are specified. For example, in the code block below, an array of data type “int” is created and the elements of this array are 10 numbers ranging from 0 to 9:

package main

import "fmt"

func main() {
    var a [10]int
    for i := 0; i < 10; i++ {
        a[i] = i
    }
    fmt.Println(a)  // Output: [0 1 2 3 4 5 6 7 8 9]
}

In the example below, it is trying to add a new data to the array. In this case, a runtime error will occur.

package main

import "fmt"

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

    a[5] = 6  // This line will cause a runtime error

    fmt.Println(a)  // This line will not be executed
}

Error:

invalid argument: index 5 out of bounds [0:5]

Slice

Slice data type, on the other hand, is a dynamic-length data structure that is not fixed-length, unlike arrays. The number of elements is not specified when defining slices.

Slices are used more often than arrays because they are more flexible and useful. For example, we can add, delete or change elements dynamically on slices.

Below is an example of creating a slice and adding a new element to it.

package main

import "fmt"

func main() {
    // Create a slice with the shorthand syntax
    a := []int{1, 2, 3, 4, 5}

    // Add a new element to the slice
    a = append(a, 6)

    // Print the slice
    fmt.Println(a)  // Output: [1 2 3 4 5 6]
}

In addition, when we create slices over an array, a connection is created between the slice we created and the original array, and the changes we make on the slice are also reflected in the original array.

package main

import "fmt"

func main() {
    a := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    b := a[0:3]
    b = append(b, 10)
    fmt.Println(a)  // Output: [0 1 2 3 4 5 6 7 8 9 10]
    fmt.Println(b)  // Output: [0 1 2 10]
}

Another advantage of slices is that they can be created with the “make” function. Slices created with the “make” function allocate space for the specified number of elements, and the slice’s elements take default values. For example, in the code block below, a slice of data type “int” is created and the elements of this slice have the value 0:

package main

import "fmt"

func main() {
    a := make([]int, 5)
    fmt.Println(a)  // Output: [0 0 0 0 0]
}

While creating slices with the “make” function, a third parameter can be given, and this parameter determines the “capacity” property of the slice. For example, in the code block below, when creating the slice named “b” with the “make” function, we specified the “capacity” property as 10:

package main

import "fmt"

func main() {
    // Create a slice with make function
    b := make([]int, 5, 10)  // Creates a slice with 5 elements and capacity 10
    b[0] = 1
    b[1] = 2
    b[2] = 3
    b[3] = 4
    b[4] = 5

    // Print the slice and its capacity
    fmt.Println(b)        // Output: [1 2 3 4 5]
    fmt.Println(len(b))   // Output: 5
    fmt.Println(cap(b))   // Output: 10
}

The length of a slice refers to the number of items currently in the slice, while capacity refers to the number of items the slice can hold before it needs to be reallocated.


Resources