Go Slice Tutorial
In this Go tutorial we learn how to reference an array with slices. We learn how to create slices from arrays, how to create empty slices as well as subslices of slices.
We also discuss how to get the length and capacity of a slice, how to add values to a slice, and how to copy values to an empty slice.
What is a Slice in Go
A slice is a reference to an array. A slice doesn’t store any data but instead references the data of an array.
If we change the elements of a slice, it will also modify the elements in the array that the slice references. If another slice is referencing the same array, its values will also change.
package main
import "fmt"
func main() {
// array
var employee = [] string {
"John",
"Jane",
"Jack",
"Jill",
}
fmt.Printf("Array: %s\n", employee)
// slice elements 0 to < 2
// from the employee array
// and store them here
slice := employee[0:2]
fmt.Printf("Slice: %s\n", employee)
// modifying an element
// in the slice
slice[0] = "Banana"
// modifies the element
// in the employee array
fmt.Printf("Array: %s\n", employee)
}
How to define a nil slice
Go provides us with multiple methods of defining a slice.
We can define a slice with an unspecified size, similar to how we would create an array.
var slice_name [] type
When we create a slice using the method above, it will be initialized as nil.
nil represents the absense of a value.
package main
import "fmt"
func main() {
var slice [] int
if (slice == nil) {
fmt.Println("slice is nil")
}
}
We can also use the make() function. The make() function takes 3 arguments, the type, length, and capacity.
var slice_name = make([] type, length, capacity)
A slice created with the make() function will be initialized with a default value for its type.
For example, a slice of type int will have values of 0, and a slice of type string will have values of “”.
package main
import "fmt"
func main() {
var slice = make([] int, 5, 5)
fmt.Println(slice)
}
How to create a subslice
We can specify upper and lower-bound values to create a subslice. Bounds are specified between square brackets and are separated by a colon.
slice_name := array_or_slice_name[lower-bound:upper-bound]
The lower bound is where the slice should start, the upper bound is where the slice should stop.
As an example, let’s consider an array with 5 elements. If we specify the lower-bound to be 0, the slice will start at element 0.
If we specify our upper-bound as 3, the slice will stop at element number 2. Essentially it works lower-bound to 1 less than upper-bound.
package main
import "fmt"
func main() {
// array
var employee = [] string {
"John",
"Jane",
"Jack",
"Jill",
}
// slice elements 2 and 3
// of employee array
slice := employee[2:4]
// slice element 1
// of slice
subslice := slice[1:2]
fmt.Printf("Array: %s\n", employee)
fmt.Printf("Slice: %s\n", slice)
fmt.Printf("Subslice: %s\n", subslice)
}
In the example above, we slice elements 2 and 3 from the array. Our slice then contains the names ‘Jack’ and ‘Jill’.
Then, we create a subslice with element 1 from the original slice, which is ‘Jill’.
Slice length and capacity
Two of the components of a slice is its length and its capacity.
- Length is the total number of elements in the slice.
- Capacity is the maximum size up to which the slice can expand.
Go provides us with two handy functions that return these values, len() and cap().
len(slice_name) // length
cap(slice_name) // capacity
package main
import "fmt"
func main() {
// array
var employee = [] string {
"John",
"Jane",
"Jack",
"Jill",
}
// slice only 2 elements
slice := employee[2:4]
fmt.Printf("Len: %d\nCap: %d\n", len(slice), cap(slice))
}
How to add values to a slice with append()
We can add a value to a slice by using the append() function.
The append function takes two arguments:
- The slice that we want to add the value to
- The value, which must be of the same type as the slice
append(slice_name, value)
package main
import "fmt"
func main() {
// array
var employee = [] string {
"John",
"Jane",
"Jack",
"Jill",
}
// slice 2 elements
slice := employee[2:4]
// Add a value to the slice
slice = append(slice, "Bananaman")
fmt.Println(slice)
fmt.Println(employee)
}
In the example above, we add a single string value to our slice.
How to copy values to an empty slice
Go provides us with the copy() function to copy values to an empty slice.
The copy() function accepts to arguments:
- Destination
- Source
copy(destination, source)
Note that the empty slice that we are copying to, must have the same type as the source slice.
package main
import "fmt"
func main() {
// array
var employee = [] string {
"John",
"Jane",
"Jack",
"Jill",
}
// 2 empty elements
var slice = make([] string, 2, 2)
// Copy from employee to
// empty slice
result := copy(slice, employee)
fmt.Printf("%d values copied\n", result)
fmt.Println("Slice: ", slice)
fmt.Println("Array: ", employee)
}
In the example above, we copy the first two element of the employee array into the empty slice.
It only copied two elements because the empty slice only has two elements, not because we specified it.
Summary: Points to remember
- A slice is a reference to an array and doesn’t store any data.
- If we change values in a slice, the underlying values in the array will change as well.
- Empty slices are initialized with either nil or the zero value for its type (ie. int = 0, string = “”).
- We can create a subslice of a slice.
- We can get the length and capacity of a slice with the len() and cap() functions respectively.
- To add a value to a slice, we use the append() function.
- The appended value must have the same type as the slice.
- To copy elements to an empty slice, we use the copy() function.
- The destination is the first parameter, the source is the second parameter.
- The destination slice must be of the same type as the source slice.