≡ Menu

GoLang Array vs Slice – 17 Slice Examples in Go Programming Language

[GoLang Slice Examples]Slice is an essential component of Go programming language.

When writing a go program, for most common use-cases, you’ll be using slice instead of array.

An array is fixed in size. But slices can be dynamic. The number of elements in a slice can grow dynamically.

But, keep in mind that slice uses array in the backend. Slice by itself doesn’t store any data. Think of slice like a reference to an array. All it does is to describe part of the underlying array.

This tutorial explains the following slice concepts:

  1. Declare Slice Variable and Make a Slice with X number of Elements
  2. Declare and Initialize Slice at the same time without using Make
  3. Initialize a Slice using Multi-Line Syntax
  4. Assign a Value to a Specific Element in a Slice
  5. Access a particular Element in a Slice
  6. Display All or Specific Elements from a Slice
  7. Create Slice with Low and High values using Colon Syntax
  8. Slice Refers to an Array underneath – Implication of Changing Slice Element Value
  9. Slice of Structs
  10. Identify Length of a Slice – How many Elements are there?
  11. Slice Capacity – Length vs Capacity
  12. Empty Slice without an Array Underneath
  13. Append one or more Elements to an existing Slice
  14. Copy elements from one Slice to another (Duplicate Slice)
  15. Two Dimensional Slices
  16. Loop through Slice Elements using For and Range
  17. Loop through a Slice and get only the Values (Ignore Slice Index)
  18. Full Working GoLang Code with All Slice Examples

For details on Go Array, refer to our previous tutorial: 12 Practical Go Array Examples

1. Declare Slice Variable and Make a Slice with X number of Elements

The following example creates a slice with an initial size of 5.

var distros []string
distros = make([]string, 5)

In the above:

  • var – keyword
  • distros – name of the slice variable
  • [] – This indicates that distros is a slice
  • The type followed by [] indicates the type of the slice. In this case, the slice is of type string. So, we can store string elements in the distros slice

Declare Slice Variable and Make at the same time

ids := make([]int, 5)

When you give := you can declare and initialize the variable at the same time.

2. Declare and Initialize Slice at the same time without using Make

The easy way to create a slice and initialize with a value is as shown below. Instead of declaring a slice variable first, and then initializing the values separately, you can combine them together.

os := []string{"Linux", "Mac", "Windows"}
fibonacci := []int{1, 1, 2, 3, 5, 8}

In the above:

  • You don’t need to use make command to initialize the size.
  • Also, you don’t have to specify the number of elements in the slice. It already knows that based on the number of values that is getting assigned to the slice during initialization.

3. Initialize a Slice using Multi-Line Syntax

For better clarify and redability, you can also use multi-line syntax while initializing and assigning values to a slice as shown below.

temperature := []float64{
     98.5,
     65.5,
     83.2,
}

But, keep in mind that in the multi-line syntax, you have to specify a comma after the last element. As you see above, there is a comma after 83.2

The advantage of this syntax is that you can comment out a particular value in a slice without having to worry about removing the comma as shown below. In the following example, we have commented out the last value in the array. But, we didn’t have to worry about removing the comma after Alicia.

names := []string{
     "John",
     "Jason",
     "Alica",
     // "Rita",
}

4. Assign a Value to a Specific Element in a Slice

This is exactly same as array. No difference between array and slice while assigning a value, as assigning a value to a slice is really assigning value to the array that is behind the slice.

distros[0] = "Ubuntu"
distros[1] = "CentOS"
distros[2] = "RedHat"

ids[0] = 1
ids[1] = 2
ids[2] = 3

In the above:

  • As you see above, the index reference that you’ll use for the 1st element of the array is 0 (not 1).
  • distros[0] refers to the 1st element in the distros array
  • ids[2] refers to the 3rd element in the ids array (which is also the last element of ids slice in this example)

5. Access a particular Element in a Slice

mydistro := distros[1]

myid := ids[3]

In the above:

  • We are assigning the value of 1st element of distros slice to mydistro variable
  • Assigning 3rd element of the ids slice to myid variable
  • := will declare and initialize the variable at the same time
  • Also, for := you don’t need to specify the type of the mydistro or myid variable
  • := know will decide the type of the variable based on the value that is getting assigned.
  • So, mydistro will become string variable, and myid will become int variable automatically

6. Display All or Specific Elements from a Slice

fmt.Println(distros)
fmt.Println(ids)

fmt.Println("distros[2] = ", distros[2])
fmt.Println("ids[2] = ", ids[2])

To display a specific slice element or all the elements in a slice, use fmt.Println as show above.

Make sure “fmt” package is imported on the top using import command.

When you print the whole slice, in the output, it will display all the elements inside square parentheses as shown below.

[1 2 3 4 5]
[Ubuntu CentOS RedHat]

7. Create Slice with Low and High values using Colon Syntax

Syntax:

slice[low:high]

In the above:

  • Low – indicates the index where the slice starts
  • High – indicates the index where the slice ends it (but excluding the index. i.e high-1).
top3 := distros[0:3]
fmt.Println(top3)

In the above:

  • 0 indicates the low value. The slice index starts from 0.
  • 3 indicates the high values. The slice index ends at 2. i.e 3-1.
  • So, the distros has three elements: distros[0], distros[1], distros[2]

Low and high are optional. Default low value is 0. Default high value is same as the length of the array.

all := distros[:]

All of the following are same:

all := distros[:]
all = distros[0:len(distros)]
all = distros[0:5]

You can also specify just either low or high. Starts from 4th element until the end. (Ignores the 1st three)

partial := distros[3:]

Display Just the 1st two elements. Starts from 0 and until 2nd element (which is really index of 1)

partial = distros[:2]

Note that the following are all same.

distros[0:5]
distros[:5]
distros[0:]
distros[:]

8. Slice Refers to an Array underneath – Implication of Changing Slice Element Value

Changing a value of an element is Slice changes the value of the underlying Array

Because this is sharing the copy of the value

top2Slice := distros[0:2]
top3Slice := distros[0:3]

top2Slice[0] = "Fedora"

Note: The above will change the value of both top2Slice[0] and top3Slice[0], because both are sharing the same array underneath.

9. Slice of Structs

You can create a slice of structs and initialize it at the same time as shown below.

books := []struct {
    id int
    name string
    available bool
  }{
    {1, "Linux-Book", true},
    {3, "Windows-Book", false},
    {5, "Mac-Book", true},
  }

10. Identify Length of a Slice – How many Elements are there?

len function will return the total number of elements in the given slice. You can assign the value of the len function to another variable also.

sliceSize := len(distros)

fmt.Println("Number of distros = ", len(distros))
fmt.Println("Number of ids = ", len(ids))

11. Slice Capacity – Length vs Capacity

A slice has both length and capacity:

  • length – the number of elements in a slice
  • capacity – total number of elements in the slice’s underlying array from the first element in the slice.
  • For the same slice, both the length and the capacity can be same or different.

Both of the lines below are exactly the same with length 5 and capacity 5.

distros = make([]string, 5)
distros = make([]string, 5, 5)

In the following the capacity is 5, but the length is 1.

distros = make([]string, 1, 5)

To identify length of an existing slice use len function as shown below.

fmt.Println("length = ", len(distros))

To identify the capacity of a slice use cap function as shown below.

fmt.Println("capacity = ", cap(distros))

12. Empty Slice without an Array Underneath

A nil slice has a length and capacity of 0 and has no underlying array as shown below.

var mySlice []string
if mySlice == nil {
  fmt.Println("mySlice is empty!")
}

The following is not a nil slice, as we’ve allocated an array, eventhough the length and capacity is 0.

yourSlice := make([]string, 0)
if yourSlice != nil {
  fmt.Println("yourSlice is not empty!")
}

13. Append one or more Elements to an existing Slice

To add additional elements to an existing slice, use the append function as shown below.

The following will add 1 additional element to the names slice and assign the results to myNames slice.

myNames := append(names, "Nick")
fmt.Println(myNames)

The following will just add 2 additional elements to the MyNames slice.

myNames = append(myNames, "Rita", "Pam")

14. Copy elements from one Slice to another (Duplicate Slice)

Use the copy function to copy the elements from one slice to another as shown below.

duplicateNames := make([]string, len(myNames))
copy(duplicateNames, myNames)

15. Two Dimensional Slices

Go’s arrays and slices are one-dimensional. To create the equivalent of a 2D array or slice, it is necessary to define an array-of-arrays or slice-of-slices, like this:

count := 1
var multi = make([][]int, 4)
 for i := 0; i < 4; i++ {
     multi[i] = make([]int, 2)
     for j := 0; j < 2; j++ {
         multi[i][j] = count
         count++
     }
 }

16. Loop through Slice Elements using For and Range

This is similar to loop through elements in an Array using for and range as shown below.

for index, value := range distros {
 fmt.Println(index, " = ", value)
}

In the above:

  • range distros – range is a go command which will return the index number and the value of an element.
  • You can assign the output of the range command to a for loop and loop through all the elements
  • for i, value – Here specify two variable to the for command. The variable name can be anything. It just happened for clarity we are using index and value as the variable name here.

17. Loop through a Slice and get only the Values (Ignore Slice Index)

If you just want to use the array element and not the index, then specifying the index variable as shown below will give error message.

In this example, we just want to loop through all the values in the ids array and total them. So, we really don’t care about the index variable here.

total := 0
for index, value := range ids {
 total = total + value
}
fmt.Println("total of all ids = ", total)

The above will throw the following error:

./slice.go:54:7: index declared and not used

In this case, just replace the index variable in the for loop with _ underscore as shown below.

for _, value := range ids {
 total = total + value
}

An _ underscore indicates Go language that you take the value of a particular variable (in this case index) and just ignore it.

18. Go Code with All Slice Examples

package main

import "fmt"

func slice() {

  // 1. Declare Slice variable and Make
  fmt.Println("1. Declare Slice variable and Make : ")

  var distros []string
  distros = make([]string, 5)
  distros[0] = "Ubuntu"
  distros[1] = "CentOS"
  distros[2] = "RedHat"
  distros[3] = "Debian"
  distros[4] = "OpenBSD"

  mydistro := distros[1]
  fmt.Println("mydistro = ", mydistro)
  fmt.Println("distros[2] = ", distros[2])
  fmt.Println("distros = ", distros)
  fmt.Println("Number of distros = ", len(distros))

  // 2. Combine Declare Slice Variable and Make
  fmt.Println()
  fmt.Println("2. Combine Declare Slice Variable and Make : ")

  ids := make([]int, 5)
  ids[0] = 1
  ids[1] = 2
  ids[2] = 3
  ids[3] = 4
  ids[4] = 5

  myid := ids[3]
  fmt.Println("myid = ", myid)
  fmt.Println("ids[2] = ", ids[2])
  fmt.Println("ids = ", ids)
  fmt.Println("Number of ids = ", len(ids))

  // 3. Declare and Initialize Slice at the same time without using Make
  fmt.Println()
  fmt.Println("3. Declare and Initialize Slice at the same time : ")

  os := []string{"Linux", "Mac", "Windows"}
  fmt.Println("os = ",os)
  fmt.Println("Number of os = ", len(os))

  fibonacci := []int{1, 1, 2, 3, 5, 8}
  fmt.Println("fibonacci = ",fibonacci)

  // Multi-line Slice Initialization Syntax
  fmt.Println()
  fmt.Println("4. Multi-line Slice Initialization Syntax : ")

  temperature := []float64{
       98.5,
       65.5,
       83.2,
  }
  fmt.Println("temperature = ", temperature)

  names := []string{
       "John",
       "Jason",
       "Alica",
       // "Rita",
  }
  fmt.Println("names = ", names)

  // Create Slice with Low and High values using Colon Syntax
  fmt.Println()
  fmt.Println("5. Create Slice with Low and High values using Colon Syntax")
  top3 := distros[0:3]
  fmt.Println(top3)

  all := distros[:]
  fmt.Println(all)

  all = distros[0:len(distros)]
  fmt.Println(all)

  all = distros[0:5]
  fmt.Println(all)

  partial := distros[3:]
  fmt.Println(partial)

  partial = distros[:2]
  fmt.Println(partial)

  // Slice Refers to an Array underneath - Implication of Changing Slice Element Value
  fmt.Println()
  fmt.Println("6. Slice Refers to an Array underneath - Implication of Changing Slice Element Value")

  top2Slice := distros[0:2]
  top3Slice := distros[0:3]
  fmt.Println(top2Slice, top3Slice)

  top2Slice[0] = "Fedora"
  fmt.Println(top2Slice, top3Slice)

  // Slice of Structs
  fmt.Println()
  fmt.Println("7. Slice of Structs")
  books := []struct {
  		id int
  		name string
      available bool
  	}{
  		{1, "Linux-Book", true},
  		{3, "Windows-Book", false},
  		{5, "Mac-Book", true},
  	}
  fmt.Println(books)

  // Slice Length and Capacity
  fmt.Println()
  fmt.Println("8. Slice Length and Capacity")
  demo := make([]string, 5)
  fmt.Println("length = ",len(demo), " capacity = ", cap(demo), demo)
  demo = make([]string, 5, 5)
  fmt.Println("length = ",len(demo), " capacity = ", cap(demo), demo)
  demo = make([]string, 1, 5)
  fmt.Println("length = ",len(demo), " capacity = ", cap(demo), demo)

  // Is Slice Empty - No Array Behind it?
  fmt.Println()
  fmt.Println("9. Is Slice Empty - No Array Behind it?")
  var mySlice []string
  if mySlice == nil {
    fmt.Println("mySlice is empty!")
  }

  yourSlice := make([]string, 0)
  if yourSlice != nil {
    fmt.Println("yourSlice is not empty!")
  }

  // Append to a Slice - Add elements
  fmt.Println()
  fmt.Println("10. Append to a Slice - Add elements")
  myNames := append(names, "Nick")
  fmt.Println(myNames)

  myNames = append(myNames, "Rita", "Pam")
  fmt.Println(myNames)

  // Copy one Slice to another
  fmt.Println()
  fmt.Println("11. Copy one Slice to another")
  duplicateNames := make([]string, len(myNames))
  copy(duplicateNames, myNames)
  fmt.Println("Original : ", myNames)
  fmt.Println("Copied   : ", duplicateNames)

   // Loop through Slice using For and Range
   fmt.Println()
   fmt.Println("12. Loop through Slice using For and Range : ")
   for index, value := range distros {
     fmt.Println(index, " = ", value)
   }

   // Loop through Slice using For and Range (Ignore Index)
   fmt.Println()
   fmt.Println("13. Loop through Slice using For and Range (Ignore Index) : ")

   total := 0
   for _, value := range ids {
     total = total + value
   }
   fmt.Println("total of all ids = ", total)

   // Multi dimensional Slice
   fmt.Println()
   fmt.Println("14. Multi dimensional Slice : ")
   count := 1
   var multi = make([][]int, 4)
    for i := 0; i < 4; i++ {
        multi[i] = make([]int, 2)
        for j := 0; j < 2; j++ {
            multi[i][j] = count
            count++
        }
    }
    fmt.Println("Slice 4 x 2 : ", multi)
}

Full output for the above example code:

1. Declare Slice variable and Make :
mydistro =  CentOS
distros[2] =  RedHat
distros =  [Ubuntu CentOS RedHat Debian OpenBSD]
Number of distros =  5

2. Combine Declare Slice Variable and Make :
myid =  4
ids[2] =  3
ids =  [1 2 3 4 5]
Number of ids =  5

3. Declare and Initialize Slice at the same time :
os =  [Linux Mac Windows]
Number of os =  3
fibonacci =  [1 1 2 3 5 8]

4. Multi-line Slice Initialization Syntax :
temperature =  [98.5 65.5 83.2]
names =  [John Jason Alica]

5. Create Slice with Low and High values using Colon Syntax
[Ubuntu CentOS RedHat]
[Ubuntu CentOS RedHat Debian OpenBSD]
[Ubuntu CentOS RedHat Debian OpenBSD]
[Ubuntu CentOS RedHat Debian OpenBSD]
[Debian OpenBSD]
[Ubuntu CentOS]

6. Slice Refers to an Array underneath - Implication of Changing Slice Element Value
[Ubuntu CentOS] [Ubuntu CentOS RedHat]
[Fedora CentOS] [Fedora CentOS RedHat]

7. Slice of Structs
[{1 Linux-Book true} {3 Windows-Book false} {5 Mac-Book true}]

8. Slice Length and Capacity
length =  5  capacity =  5 [    ]
length =  5  capacity =  5 [    ]
length =  1  capacity =  5 []

9. Is Slice Empty - No Array Behind it?
mySlice is empty!
yourSlice is not empty!

10. Append to a Slice - Add elements
[John Jason Alica Nick]
[John Jason Alica Nick Rita Pam]

11. Copy one Slice to another
Original :  [John Jason Alica Nick Rita Pam]
Copied   :  [John Jason Alica Nick Rita Pam]

12. Loop through Slice using For and Range :
0  =  Fedora
1  =  CentOS
2  =  RedHat
3  =  Debian
4  =  OpenBSD

13. Loop through Slice using For and Range (Ignore Index) :
total of all ids =  15

14. Multi dimensional Slice :
Slice 4 x 2 :  [[1 2] [3 4] [5 6] [7 8]]
Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book