Go Language Slices
Go language slices are an abstraction over arrays.
Go arrays have a fixed length, which makes them unsuitable for certain scenarios. Go provides a flexible and powerful built-in type called slice ("dynamic array"). Unlike arrays, the length of a slice is not fixed and can be appended with elements, which may increase the slice's capacity.
Defining a Slice
You can declare an array without specifying its size to define a slice:
var identifier []type
A slice does not need to specify its length.
Or you can use the make() function to create a slice:
var slice1 []type = make([]type, len)
It can also be abbreviated as
slice1 := make([]type, len)
You can also specify the capacity, where capacity is an optional parameter.
make([]T, length, capacity)
Here, len is the length of the array and also the initial length of the slice.
Slice Initialization
s :=[] int {1,2,3 }
Directly initialize a slice, []
indicates the slice type, {1,2,3} initializes the values as 1,2,3
, with cap=len=3.
s := arr[:]
Initialize slice s, which is a reference to array arr.
s := arr[startIndex:endIndex]
Create a new slice from arr with elements from index startIndex to endIndex-1.
s := arr[startIndex:]
When endIndex is default, it represents up to the last element of arr.
s := arr[:endIndex]
When startIndex is default, it represents from the first element of arr.
s1 := s[startIndex:endIndex]
Initialize slice s1 from slice s.
s :=make([]int,len,cap)
Initialize slice s using the built-in function make(), []int indicates a slice with elements of type int.
len() and cap() Functions
Slices are indexable and their length can be obtained using the len() method.
Slices provide a method cap() to measure the maximum capacity of the slice.
Here is a specific example:
Example
package main
import "fmt"
func main() {
var numbers = make([]int,3,5)
printSlice(numbers)
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}
The output of the above example is:
len=3 cap=5 slice=[0 0 0]
Nil Slice
A slice is nil by default before initialization and has a length of 0. Here is an example:
Example
package main
import "fmt"
func main() {
var numbers []int
printSlice(numbers)
if(numbers == nil){
fmt.Printf("The slice is empty")
}
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}
The output of the above example is:
len=0 cap=0 slice=[]
The slice is empty
Slice Slicing
You can set the lower and upper bounds to slice a slice [lower-bound:upper-bound]. Here is an example:
Example
package main
import "fmt"
func main() {
/* Create a slice */
numbers := []int{0,1,2,3,4,5,6,7,8}
printSlice(numbers)
/* Print the original slice */
fmt.Println("numbers ==", numbers)
/* Print the sub-slice from index 1 (inclusive) to index 4 (exclusive) */
fmt.Println("numbers[1:4] ==", numbers[1:4])
/* Default lower bound is 0 */
fmt.Println("numbers[:3] ==", numbers[:3])
/* Default upper bound is len(s) */
fmt.Println("numbers[4:] ==", numbers[4:])
numbers1 := make([]int,0,5)
printSlice(numbers1)
}
/* Print sub-slice from index 0 (inclusive) to index 2 (exclusive) */
number2 := numbers[:2]
printSlice(number2)
/* Print sub-slice from index 2 (inclusive) to index 5 (exclusive) */
number3 := numbers[2:5]
printSlice(number3)
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}
Executing the above code outputs:
len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8]
numbers == [0 1 2 3 4 5 6 7 8]
numbers[1:4] == [1 2 3]
numbers[:3] == [0 1 2]
numbers[4:] == [4 5 6 7 8]
len=0 cap=5 slice=[]
len=2 cap=9 slice=[0 1]
len=3 cap=7 slice=[2 3 4]
append() and copy() Functions
If you want to increase the capacity of a slice, we must create a new, larger slice and copy the contents of the original slice into it.
The following code describes the copy method for copying slices and the append method for adding new elements to a slice.
Example
package main
import "fmt"
func main() {
var numbers []int
printSlice(numbers)
/* Allow appending an empty slice */
numbers = append(numbers, 0)
printSlice(numbers)
/* Add one element to the slice */
numbers = append(numbers, 1)
printSlice(numbers)
/* Add multiple elements simultaneously */
numbers = append(numbers, 2,3,4)
printSlice(numbers)
/* Create slice numbers1 with double the capacity of the previous slice */
numbers1 := make([]int, len(numbers), (cap(numbers))*2)
/* Copy the contents of numbers to numbers1 */
copy(numbers1,numbers)
printSlice(numbers1)
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}
The output of the above code execution is:
len=0 cap=0 slice=[]
len=1 cap=1 slice=[0]
len=2 cap=2 slice=[0 1]
len=5 cap=6 slice=[0 1 2 3 4]
len=5 cap=12 slice=[0 1 2 3 4]