Welcome to Golang Programs, Get the best new programs in your inbox, daily.

Slices

A slice is a flexible and extensible data structure to implement and manage collections of data. A slice is a segment of dynamic arrays that can grow and shrink as you see fit. Like arrays, slices are indexable and have a length. Unlike arrays they're flexible in terms of length because they have their own built-in function called append, which can grow a slice quickly with efficiency. You can also trim the size of a slice by slicing out a part of the hidden memory.

Slices helps us in indexing, iteration, and garbage collection optimizations because the hidden memory is allocated in adjoining blocks.

A slice has three components: a pointer, a length, and a capacity.
The pointer points to the first element of the array that is reachable through the slice, which is not necessarily the array's first element.

The length is the number of elements referred to by the slice.
The capacity is the number of elements for which there is space allocated in the slice.
The built-in functions len and cap returns length and capacity of slices.

Declaration of Nil Slice

A nil slice is the most common way to create slices in Go. Declaring a slice is similar to declaring an array, but when you declare slices, you don't need to specify the size because it is a dynamic array.

Here's an example of a slice:

var num []int
var city []string
var series []float64

In this case num,city and series has been declared as a nil slice of integer,string and float64 respectively. At this moment, the length and capacity of the slice is zero.
Although the length of num,city and series is now zero, you can modify the length and initialize values later because slices are dynamic arrays. Go provides a function append that can be used to enlarge any slice (nil or nonnil) later on. They can be used with many of the standard library and built-in functions that work with slices.

package main
import "fmt"
func main() {
	var num []int
	var city []string
	var series []float64
	fmt.Println(num,len(num),cap(num))
	if num==nil{
		fmt.Println("Nil")
	}	
	fmt.Println(city,len(city),cap(city))
	if city==nil{
		fmt.Println("Nil")
	}
	fmt.Println(series,len(series),cap(series))
	if series==nil{
		fmt.Println("Nil")
	}
}

Creating and initializing Slices Using make Function

A slice must be initialized before assigning values. Go's built-in make function is used to initialize slices. When slices are declared using the make function, length and capacity are provided as arguments.

If you want to create a slice, you should use the built-in make function:

make([]T, len)
make([]T, len, cap)

Example: to create a slice using the make function specifying only the length.

num:= make([]int, 5)

A slice num is declared and initialized with length of 5 and capacity of 5. Because the value of capacity is not provided, it defaults to the value of length.

Example: to create a slice using the make function specifying both the length and capacity.

num:= make([]int, 5,6)

A slice num is declared and initialized with a length of 5 and capacity of 6 using the make function.

Example: to assign values to slice num.

num[0] = 10
num[1] = 20
num[2] = 30

Declaring a slice with a slice literal

Example to create a slice using a slice literal:

test1:= []int {5,10,15,20,25}

A slice test1 is declared and initialized with length of 5 and capacity of 5.

Example to create empty slice by using a slice literal:

test2:= []int {}

Note that nil slices and empty slices are different. If test2 is an empty slice, a code expression test2 == nil returns false , but if it is a nil slice, the expression test2 == nil returns true.

Example to provide values to specific indexes at the time of initialize the values:

test3:= []int {0:9, 2:18, 5:27}

A slice test3 is declared and initialized with length of 6 and capacity of 6.

Example to create a slice by simply providing the highest index:

test4:= []int {7:0}

The length and capacity 8 is determined by the highest index value 7 specified.

// GO language program of Creating Slices Using a Slice Literal
package main
import "fmt"
func main() {
	test1:= []int {5,10,15,20,25}
	fmt.Println(test1,len(test1),cap(test1))
	test2:= []int {}
	fmt.Println(test2,len(test2),cap(test2))
	test3:= []int {0:9, 2:18, 5:27}
	fmt.Println(test3,len(test3),cap(test3))
	test4:= []int {7:0}
	fmt.Println(test4,len(test4),cap(test4))
}
/*
Output 
C:\golang>go run slice.go
[5 10 15 20 25] 5 5
[] 0 0
[9 0 18 0 0 27] 6 6
[0 0 0 0 0 0 0 0] 8 8
*/

The append Function

append adds elements onto the end of a slice. If there's sufficient capacity in the underlying array, the element is placed after the last element and the length is incremented. However, if there is not sufficient capacity, a new array is created, all of the existing elements are copied over, the new element is added onto the end, and the new slice is returned.

// GO language program to enlarge a slice using the append Function
package main
import (
"fmt"
)
func main() {
	// Create a smaller slice
	a := make([]int, 2, 5)
	a[0] = 10	
	a[1] = 20	
	fmt.Println("Slice A:", a)
	fmt.Printf("Length is %d Capacity is %d\n", len(a), cap(a))
	// Create a bigger slice
	a = append(a, 30, 40, 50)
	fmt.Println("Slice A after appending data:", a)
	fmt.Printf("Length is %d Capacity is %d\n", len(a), cap(a))	
}
/*
Output 
C:\golang>go run slice.go
Slice A: [10 20]
Length is 2 Capacity is 5
Slice A after appending data: [10 20 30 40 50]
Length is 5 Capacity is 5
*/

The copy Function

Go's built-in copy function is used to copy data from one slice to another. copy takes two arguments: dst and src. All of the entries in src are copied into dst overwriting whatever is there. If the lengths of the two slices are not the same, the smaller of the two will be used.

// GO language program to enlarge a slice using the Copy Function
package main
import (
"fmt"
)
func main() {
	// Create a smaller slice
	a := []int{5, 6, 7}
	fmt.Printf("[Slice:A] Length is %d Capacity is %d\n", len(a), cap(a))
	// Create a bigger slice
	b := make([]int, 5, 10)
	copy(b, a)	// copy function
	fmt.Printf("[Slice:B] Length is %d Capacity is %d\n", len(b), cap(b))
	fmt.Println("Slice B after copying:", b)
	b[3] = 8
	b[4] = 9
	fmt.Println("Slice B after adding elements:", b)
}
/*
Output 
C:\golang>go run slice.go
[Slice:A] Length is 3 Capacity is 3
[Slice:B] Length is 5 Capacity is 10
Slice B after copying: [5 6 7 0 0]
Slice B after adding elements: [5 6 7 8 9]
*/