Go Slices: Declare, Access, and Iterate Slices

Slice is a lightweight and flexible data structure in Go. Slices store multiple elements of the same type in a single variable same as arrays. But unlike arrays, a slice's length can grow and shrink as needed.

Slice Declaration

A slice is declared like an array but without specifying the size as it can grow or shrink as per the requirement.

A slice can be declared in any of the following three methods

  1. Using the []datatype { values } syntax.
  2. From an Array.
  3. Using the make() function.

Create a slice using []datatype{values}

This is the most common method of creating a slice in Go.

Syntax: Declare Slice
sliceName := []datatype { value1, value2, value3,...valueN }

The following creates int and string type slices:

Example: Declare Slices
emptySlice := []int {}
oddnums := []int { 1, 3, 5, 7, 9}
cities := []string {"Mumbai","New York","London","Paris",}

fmt.Println(emptySlice) //output: []
fmt.Println(oddnums) //output: [1 3 5 7 9]
fmt.Println(cities) //output: [Mumbai New York London Paris] 

Unlike arrays, the length and the capacity of a slice can be different. Length is the number of elements in the slice and capacity is the number of elements a slice can contain. The len() returns the length and the cap() returns the capacity of a slice.

Example: Length and Capacity of Slice
oddnums := []int { 1, 3, 5, 7, 9}

fmt.Println(len(oddnums)) // output: 5
fmt.Println(cap(oddnums)) //output: 5

Create a Slice from an Array

A slice can be created by slicing a given array and by specifying the lower and higher bound.

Syntax: Create Slice from Array
myslice := myarray[start : end]

The following creates a slice from an array. The start and the end values are the starting and ending indexes for the new slice with reference to the array.

Example: Create Slice from Array
package main

import "fmt"

func main() {
    arr := []int{ 10, 20, 30, 40, 50 }

    myslice1 := arr[:0]
    printSlice(myslice1)

    myslice2 := arr[:2]
    printSlice(myslice2)
    
    myslice3 := arr[2:]
    printSlice(myslice3)
    
    myslice4 := arr[1:4]
    printSlice(myslice4)
}

func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
Output:
len=0 cap=5 []
len=2 cap=5 [10 20]
len=3 cap=3 [30 40 50]
len=3 cap=4 [20 30 40]

In the above example, slice objects are created from an array arr. The arr[:0] creates a slice with no elements because :0 ends with 0 element. The arr[:2] creates a slice starting from 0th index till 2nd index (till index 1, excludes 2nd index). The arr[2:] creates a slice starting from 2nd index till end of array. The arr[1:4] creates a slice starting from index 1 till index 3 (excludes 4th index).

Here, the length of the slice is different from the capacity. The length is total elements taken from the array whereas the capacity counted from the index of the first element taken from the array till total capacity of an array.

Using make() Function

A slice can be created using the make() function.

Syntax
 mySlice := make ([]type , length [,capacity])

The following example creates a slice using the make() function.

Example: Create Slice using make()
mySlice1 := make([]int, 4, 6)
fmt.Println(mySlice1) //output: [0 0 0 0] 
fmt.Println (len(mySlice1)) // output: 4
fmt.Println (cap(mySlice1)) //output: 6

// slice without specifying the capacity
mySlice2 := make([]int, 4)
fmt.Println(mySlice2) //output: [0 0 0 0] 
fmt.Println(len(mySlice2)) // output: 4
fmt.Println(cap(mySlice2)) //output: 4

In the above example, the first slice is defined with both the length and the capacity as 4 and 6 respectively. In the second slice definition, only length is specified. Here, the capacity takes the same value as the length.

Iterate Slice using for Loop

Use for loop to iterate and access a slice.

Example: Slice with for Loop
s := []int{10, 20, 30, 40}

for i := 0; i < len(s); i++ {
	fmt.Println(s[i])
}
Output:
10
20
30
40

You can also use the for..range loop to iterate and access a slice.

Example: for..range loop
s := []int{10, 20, 30, 40}

for indx, val := range s {
	fmt.Println (indx, val)
}

In the above example, the variable index is the index value of the element in the slice and val is the element value.

Output:
0 10
1 20
2 30
3 40

In for..range loop, if the index variable is not used, you can replace it with an underscore, as shown below.

Example: for..range loop
s := []int{10, 20, 30, 40}

for _, val := range s {
		fmt.Println(val)				
	}  
Output:
10
20
30
40