Download our all in one automation tool for various social media websites.
An array is a fixed length, however a slice is dynamically sized.
In Golang, a slice is a dynamically sized view into an array. A Slice can also be defined as a segment of an array.
Slices are references to arrays. A slice itself does not store any data instead it refers to the data stored in the underlying array.
Slices in Golang may have following components:
Program given below demonstrates various ways by which slices can be declared in Golang.
// program to demonstrate declaration of slices in Golang
package main
import "fmt"
func main() {
// declaration of array
var array1 = [8]int{1, 2, 3, 4, 5, 6, 7, 8}
fmt.Println("array1 is", array1)
// initializing a slice from an existing array
var slice1 = array1[0:4]
fmt.Println("slice1 is", slice1)
// resizing an existing slice
slice1 = slice1[0:6]
fmt.Println("slice1 is", slice1)
// initializing a new slice from an existing slice
var slice2 = slice1[0:3]
fmt.Println("slice2 is", slice2)
// slice given below refers to a newly initialized array
var slice3 = []string{"a", "b", "c", "d", "e", "f"}
fmt.Println("slice3 is", slice3)
// declaring an empty slice
var emptySlice1 = []int{}
fmt.Println("emptySlice1 is", emptySlice1)
// declaring an empty slice
var emptySlice2 []int
fmt.Println("emptySlice2 is", emptySlice2)
}
Above program produces following output:
array1 is [1 2 3 4 5 6 7 8]
slice1 is [1 2 3 4]
slice1 is [1 2 3 4 5 6]
slice2 is [1 2 3]
slice3 is [a b c d e f]
emptySlice1 is []
emptySlice2 is []
As shown in above program, output of fmt.Println
appears same for both arrays
and slices however arrays and slices and are very different in Golang.
Following lines in above demonstrates how to declare an empty slice:
var emptySlice1 = []int{}
var emptySlice2 []int
The type []T
is a slice with elements of type T
. In above program, the type
of elements is int
hence empty slice is initialized using the syntax []int
.
Length and capacity of a nil slice or empty slice is 0.
Following line in above program demonstrates how slices can be declared using indices to an existing array or existing slice
var slice1 = array1[0:4]
slice1 = slice1[0:6]
While declaring a slice from an existing slice or an array, following syntax is used:
var new_slice = array_or_slice[start:end]
Hero, start
can be any starting index of the previous array or slice, and
end
can be any index greater than start
but less then the length of the
underlying array or slice.
In above program, following line declares a new slice by providing new data.
// slice literal
var slice3 = []string{"a", "b", "c", "d", "e", "f"}
Slices are references to underlying arrays.
Above declaration works by creating a new array that contains above elements and the newly created slice references them.
Slice literals are like array literals but without the length.
// slice literal
[]int{1,2,3}
array literal:
[3]int{1,2,3}
Notice that array literals have length whereas slice literals do not have length.
Changing an element in a slice changes the elements in the underlying array because of this behaviour, all the slices that refer to elements of the underlying array are also changed.
The fact that slices are references to array is demonstrated in the program given below:
Program given below demonstrates how slices are references to arrays.
// program to demonstrate that slices are references to arrays
package main
import "fmt"
func main() {
var arrayOfAlphabets = [4]string{
"a",
"b",
"c",
"d",
}
fmt.Println("arrayOfAlphabets is:", arrayOfAlphabets)
var slice1 = arrayOfAlphabets[0:4]
fmt.Println("slice1 is:", slice1)
var slice2 = arrayOfAlphabets[0:4]
fmt.Println("slice2 is:", slice2)
// modifying slice1
slice1[0]="w"
slice1[1]="x"
slice1[2]="y"
slice1[3]="z"
fmt.Println("slice1 is modified")
// printing details of both slices
fmt.Println("slice1 is:", slice1)
fmt.Println("slice2 is:", slice2)
}
Above program produces following output:
arrayOfAlphabets is: [a b c d]
slice1 is: [a b c d]
slice2 is: [a b c d]
slice1 is modified
slice1 is: [w x y z]
slice2 is: [w x y z]
When the slice1
is modified, slice2 gets modified as well because both slices
are references to the same arrayOfAlphabets
.
Other slices that share same underlying array will be altered as well.
Program given below demonstrates the difference between a slice literal and array literal in Golang.
// program to demonstrate difference between a slice literal and array literal
package main
import "fmt"
func main() {
// array literal
var array1 = [3]string{"a", "b", "c"}
// slice literal
var slice1 = []string{"a", "b", "c"}
// printing data
fmt.Println("array1 is:",array1)
fmt.Println("slice1 is:",slice1)
}
Above program produces following output:
array1 is: [a b c]
slice1 is: [a b c]
When an array is sliced, its default bounds must be difined to specify what elements must be present in the slice.
Program given below demonstrates how default slice bound works.
// program to demonstrate default slice bounds
package main
import "fmt"
func main() {
var array1=[4]int{1,2,3,4}
// equivalent expressions
var slice1=array1[:]
var slice2=array1[0:]
var slice3=array1[:4]
var slice4=array1[0:4]
// printing data to console
fmt.Println("slice1 is:",slice1)
fmt.Println("slice2 is:",slice2)
fmt.Println("slice3 is:",slice3)
fmt.Println("slice4 is:",slice4)
}
Above program produces following output:
slice1 is: [1 2 3 4]
slice2 is: [1 2 3 4]
slice3 is: [1 2 3 4]
slice4 is: [1 2 3 4]
As demonstrated in above program, the default slice bound is equivalent as various other expressions that are declared below the default slice bound expressions.
The default slice bound starts at zero and ends at length of the underlying array.
Program given below demonstrates how custom slice bounds can be used for referring to certain elements in an array.
// program to demonstrate custom slice bounds
package main
import "fmt"
func main() {
var array1 = [4]int{1, 2, 3, 4}
fmt.Println("array1 is:", array1)
// analyzing slice default bounds
var slice1 = array1[0:1]
var slice2 = array1[1:2]
var slice3 = array1[2:3]
var slice4 = array1[3:4]
// printing data to console
fmt.Println("slice1 is:", slice1)
fmt.Println("slice2 is:", slice2)
fmt.Println("slice3 is:", slice3)
fmt.Println("slice4 is:", slice4)
}
Above program produces following output:
array1 is: [1 2 3 4]
slice1 is: [1]
slice2 is: [2]
slice3 is: [3]
slice4 is: [4]
Length of slices can be calculated by using the built in len
function,
similarly capacity of slices can be calculated by using the built in cap
function.
Program given below demonstrates use of len
and cap
functions.
Length and capacity of nil slice on empty slices is zero.
Program given below demonstrates how to calculate length and capacity of slices
using the built in len
and cap
functions.
// program to demonstrate custom slice bounds
package main
import "fmt"
func main() {
var array1 = [4]int{1, 2, 3, 4}
fmt.Println("array1 is:", array1)
var slice1 = array1[0:4]
fmt.Println("slice1 is:", slice1)
// calculating length and capacity of slice1
var lengthOfSlice1 = len(slice1)
var capacityOfSlice1 = cap(slice1)
fmt.Println("lengthOfSlice1 is:", lengthOfSlice1)
fmt.Println("capacityOfSlice1 is:", capacityOfSlice1)
slice1 = array1[3:4]
fmt.Println("slice1 is re-sliced")
// calculating length and capacity of slice2
lengthOfSlice1 = len(slice1)
capacityOfSlice1 = cap(slice1)
fmt.Println("lengthOfSlice1 is:", lengthOfSlice1)
fmt.Println("capacityOfSlice1 is:", capacityOfSlice1)
}
Above program produces following output:
array1 is: [1 2 3 4]
slice1 is: [1 2 3 4]
lengthOfSlice1 is: 4
capacityOfSlice1 is: 4
slice1 is re-sliced
lengthOfSlice1 is: 1
capacityOfSlice1 is: 1
When an existing slice is re-sliced its length and capacity changes.
Program given below demonstrates that length and capacity of nil slices is 0.
// program to demonstrate length and capacity of nil slice
package main
import "fmt"
func main() {
// nil slice
var slice1 []int
fmt.Println("slice1 is:",slice1)
fmt.Println("length of slice1 is:",len(slice1))
fmt.Println("capacity of slice1 is:",cap(slice1))
}
Above program produces following output:
slice1 is: []
length of slice1 is: 0
capacity of slice1 is: 0
An existing slice can be sliced again using subslicing. Subslicing allows to change existing slice by specifying starting and ending indexes.
// program to demonstrate sub-slicing in Golang
package main
import "fmt"
func main() {
// original slice of characters
alphabets := []string{"a", "b", "c", "d", "e", "f"}
fmt.Println("alphabets is ", alphabets)
fmt.Println("alphabets[:2] is ", alphabets[:2])
fmt.Println("alphabets[1:5] is ", alphabets[1:4])
// create a sub-slice of characters
subSlice := alphabets[:3]
// print the new sub slice
fmt.Println("subSlice is ", subSlice)
}
Above program produces following output:
alphabets : [a b c d e f]
alphabets[:2] : [a b]
alphabets[1:5] : [b c d]
subSlice : [a b c]