We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies.

We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies. Less

We use cookies and other tracking technologies... More

Login or register
to publish this job!

Login or register
to save this job!

Login or register
to save interesting jobs!

Login or register
to get access to all your job applications!

Login or register to start contributing with an article!

Login or register
to see more jobs from this company!

Login or register
to boost this post!

Show some love to the author of this blog by giving their post some rocket fuel 🚀.

Login or register to search for your ideal job!

Login or register to start working on this issue!

Login or register
to save articles!

Login to see the application

Engineers who find a new job through WorksHub average a 15% increase in salary 🚀

You will be redirected back to this page right after signin

Blog hero image

Slicing Slices in GO

Azeez Lukman 11 October, 2021 | 4 min read

Slices wrap arrays in Go and provide a more general, powerful, and convenient interface to data sequences. In this article, you will cover slice basics such as creating, initializing, and iteration. You will also learn how to grow a slice, work with subsets of slices, and slice tricks.

Slices contain a list of elements of a particular type, but unlike arrays, there are methods available to add or remove elements from the slice. This is because as the name implies, slices don't hold any actual data themselves. A slice provides a view into the elements of the underlying array and provides extra methods for interacting with the data.

slices are much more common than arrays

Slice Type

The type []T denotes a slice of type T for example:

[]string

This says hey, this is a slice of strings or this slice contains string values. The values would be comma separated. This is similar to how you would declare the type for an array variable, except the length is omitted here.

For the most part, functions for working with slices is identical to functions for working with arrays. These functions includes ones for accessing elements, using zero values, passing slices to the len function, and for...range loops.

Slice Values

Like i mentioned above, slices themselves don't store any values at all. You may be wondering how it then holds data. Slices are designed to work as a convenience wrapper for arrays, allowing you to easily perform functions that would have been difficult to manually perform directly on an array.

I like to think of a slice as a peek into some section of the underlying array. That peek is where you interact with the array from and the data you peek into is what you get to operate on.

Now, you should note that modifying the peek elements makes the actual changes into the underlying array directly. This could be a blessing and a curse at the same time since the other slices with the same underlying array would see the changes.

Declaring slices

To declare the type for a variable that holds a slice, you use an empty pair of square brackets, followed by the type of elements the slice will hold.

var intSlice []int

This only declares a slice type that holds integer values as intSlice. Declaring a slice variable doesn’t automatically create a slice. For that, you call the built-in make function. You pass make the type of the slice you want to create and the length of slice it should create and assign it to your slice variable.

var intSlice []int
intSlice = make([]int, 5)

After declaring the slice variable intSlice . The next line creates the actual slice using the data type and the length. Notice the data type passed into make function is the same as that of the slice variable.

So the make method created the slice, but hold, what about the values? By default the make method would fill the slice with the underlying data type's zero value of the slice we created for the length we passed in. In our example the slice intSlice now contains 5 values as 0

You can now use the builtin slice methods, let's run a few on the newly created slice.

len(intSlice) //4
intSlice[3] // 0

Next, we want to fill those spots up with our actual data, you would assign its elements using the same syntax you used for accessing it.

intSlice[0] = 10 
intSlice[1] = 8
intSlice[2] = 9 
intSlice[3] = 12

fmt.Println(inSlice[0])  // 10
fmt.Println(inSlice[1])  // 8
fmt.Println(inSlice)  // 10, 8, 9, 12, 0, 0
Join our newsletter
Join over 111,000 others and get access to exclusive content, job opportunities and more!

Slice literal

When you know the values that goes into your slice before declaring, you can directly pass them in using slice literal. With slice literal, you do not need to use the make function, your slice gets declared and assigned its values in one step

A slice literal looks just like an array literal, except the length is omitted:

stringSlice := []string{"hello","world"}

You can even use a multi line slice literal to make your more organized

stringSlice := []string{
			"hello",
			"world",
			"once",
			"more",
}

When you use a slice literal, an array is created and the slice is created to reference it, the slice gets a peek of the whole value inserted by the slice literal. The only way to access the array created is through the slice.

Slicing arrays

Using the slice operator, you can create a slice directly from the array without using the make function, the operator is similar to the one used for accessing and assigning values in slices, but it has two indexes instead, the first denotes the start of the slice and the other denotes the end, excluding that index. The elements peeked into would span from the first index up to but not including the second index.

arr = [4]{1, 2, 4, 8}
arrSlice = arr[1:3]
fmt.Println(arrSlice) // 2,4

omitting the last index causes the slice to include vlalues through to the last index of the array

arr = [4]{1, 2, 4, 8}
arrSlice = arr[1:]
fmt.Println(arrSlice) // 2,4,

The os.Args package variable contains a slice of strings with the command-line arguments the current program was run with

Add items onto a slice

Go provides a built-in append function that takes a slice, and one or more values you want to append to the end of that slice and returns a new, larger slice with all the same elements as the original slice, with the new element(s) added onto the end.

slice = []int{10, 5, 8}
append(slice, 20)
append(slice, 20)

A slice’s underlying array can’t grow in size. If there isn’t room in the array to add elements, A new, larger array would be created and all its elements will be copied into it, then the slice will be updated to refer to this new array. But since all this happens behind the scenes in the append function, there’s no easy way to tell whether the slice returned from append has the same underlying array as the slice you passed in, or a different underlying array. If you keep both slices, this can lead to some unpredictable behavior such as inconsistencies.

To avoid this, Always make sure to assign the return value of append function back to the same slice variable we passed to append

slice = []int{10, 5, 8}
slice = append(slice, 20)
slice = append(slice, 20)

Summary

Slices are a convenience wrapper around arrays, this is why they are very similar to arrays even with the methods used in manipulating them. Slices don't store value but operates on the underlying array. They can only hold one data type just like arrays too.

Other things to explore includes converting strings to slices and vice versa, you should also look into how slices are used in place of variadic arguments in variadic functions.

Thank you for reading, i'm Azeez Lukman, should you need any help or questions please feel free to reach out @robogeek95 everywhere

Author's avatar
Azeez Lukman
Lifelong learning machine, Full-stack node {MERN,MEAN} web developer

Related Issues

open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 1
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 2
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Open
  • 0
  • 0
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 1
  • Intermediate
  • HTML

Get hired!

Sign up now and apply for roles at companies that interest you.

Engineers who find a new job through WorksHub average a 15% increase in salary.

Start with GitHubStart with Stack OverflowStart with Email