Slices in Go are a flexible and efficient way to represent arrays, and they are often used in place of arrays because of their dynamic size and added features. A slice is a reference to a portion of an array. It’s a data structure that describes a portion of an array by specifying the starting index and the length of the portion. This allows you to work with a portion of an array as if it were an independent array. In Go language slice is more powerful, flexible, convenient than an array, and is a lightweight data structure. Slice is a variable-length sequence that stores elements of a similar type, you are not allowed to store different type of elements in the same slice. It is just like an array having an index value and length, but the size of the slice is resized they are not in fixed-size just like an array. Internally, slice and an array are connected with each other, a slice is a reference to an underlying array. It is allowed to store duplicate elements in the slice.
The first index position in a slice is always 0 and the last one will be (length of slice – 1).
Here’s an example that demonstrates how to create a slice in Go:
Go
package main import "fmt" func main() { array := [ 5 ]int{ 1 , 2 , 3 , 4 , 5 } slice := array[ 1 : 4 ] fmt.Println( "Array: " , array) fmt.Println( "Slice: " , slice) } |
Output:
Array: [1 2 3 4 5] Slice: [2 3 4]
In this example, the array is created with 5 elements, and the slice is created by specifying the starting index 1 and the length 4. The slice now contains the elements 2, 3, and 4 from the original array.
Slices are dynamic, which means that their size can change as you add or remove elements. Go provides several built-in functions that allow you to modify slices, such as append, copy, and delete.
Here’s an example that demonstrates how to add elements to a slice in Go:
Go
package main import "fmt" func main() { slice := []int{ 1 , 2 , 3 } slice = append(slice, 4 , 5 , 6 ) fmt.Println( "Slice: " , slice) } |
Output:
Slice: [1 2 3 4 5 6]
In this example, the function append is used to add the elements 4, 5, 6 to the slice slice. The result is a new slice that contains the elements 1, 2, 3, 4, 5, 6.
Slices in Go are a powerful and flexible data structure that can be used to represent arrays. They provide a more dynamic and efficient way to work with arrays, and they are widely used in Go programs.
Declaration of Slice
A slice is declared just like an array, but it doesn’t contain the size of the slice. So it can grow or shrink according to the requirement.
Syntax:
[]T or []T{} or []T{value1, value2, value3, ...value n}
Here, T is the type of the elements. For example:
var my_slice[]int
Components of Slice
A slice contains three components:
- Pointer: The pointer is used to points to the first element of the array that is accessible through the slice. Here, it is not necessary that the pointed element is the first element of the array.
- Length: The length is the total number of elements present in the array.
- Capacity: The capacity represents the maximum size upto which it can expand.
Let us discuss all these components with the help of an example:
Example:
Go
// Golang program to illustrate // the working of the slice components package main import "fmt" func main() { // Creating an array arr := [ 7 ] string { "This" , "is" , "the" , "tutorial" , "of" , "Go" , "language" } // Display array fmt.Println( "Array:" , arr) // Creating a slice myslice := arr[ 1 : 6 ] // Display slice fmt.Println( "Slice:" , myslice) // Display length of the slice fmt.Printf( "Length of the slice: %d" , len(myslice)) // Display the capacity of the slice fmt.Printf( "\nCapacity of the slice: %d" , cap(myslice)) } |
Output:
Array: [This is the tutorial of Go language] Slice: [is the tutorial of Go] Length of the slice: 5 Capacity of the slice: 6
Explanation: In the above example, we create a slice from the given array. Here the pointer of the slice pointed to index 1 because the lower bound of the slice is set to one so it starts accessing elements from index 1. The length of the slice is 5, which means the total number of elements present in the slice is 5 and the capacity of the slice 6 means it can store a maximum of 6 elements in it.
How to create and initialize a Slice?
In Go language, a slice can be created and initialized using the following ways:
- Using slice literal: You can create a slice using the slice literal. The creation of slice literal is just like an array literal, but with one difference you are not allowed to specify the size of the slice in the square braces[]. As shown in the below example, the right-hand side of this expression is the slice literal.
var my_slice_1 = []string{"Geeks", "for", "Geeks"}
Note: Always remember when you create a slice using a string literal, then it first creates an array and after that return a slice reference to it.
Example:
Go
// Golang program to illustrate how // to create a slice using a slice // literal package main import "fmt" func main() { // Creating a slice // using the var keyword var my_slice_1 = [] string { "Geeks" , "for" , "Geeks" } fmt.Println( "My Slice 1:" , my_slice_1) // Creating a slice //using shorthand declaration my_slice_2 := []int{ 12 , 45 , 67 , 56 , 43 , 34 , 45 } fmt.Println( "My Slice 2:" , my_slice_2) } |
Output:
My Slice 1: [Geeks for Geeks] My Slice 2: [12 45 67 56 43 34 45]
- Using an Array: As we already know that the slice is the reference of the array so you can create a slice from the given array. For creating a slice from the given array first you need to specify the lower and upper bound, which means slice can take elements from the array starting from the lower bound to the upper bound. It does not include the elements above from the upper bound. As shown in the below example:
Syntax:
array_name[low:high]
This syntax will return a new slice.
Note: The default value of the lower bound is 0 and the default value of the upper bound is the total number of the elements present in the given array.
Example:
Go
// Golang program to illustrate how to // create slices from the array package main import "fmt" func main() { // Creating an array arr := [ 4 ] string { "Geeks" , "for" , "Geeks" , "GFG" } // Creating slices from the given array var my_slice_1 = arr[ 1 : 2 ] my_slice_2 := arr[ 0 :] my_slice_3 := arr[: 2 ] my_slice_4 := arr[:] // Display the result fmt.Println( "My Array: " , arr) fmt.Println( "My Slice 1: " , my_slice_1) fmt.Println( "My Slice 2: " , my_slice_2) fmt.Println( "My Slice 3: " , my_slice_3) fmt.Println( "My Slice 4: " , my_slice_4) } |
Output:
My Array: [Geeks for Geeks GFG] My Slice 1: [for] My Slice 2: [Geeks for Geeks GFG] My Slice 3: [Geeks for] My Slice 4: [Geeks for Geeks GFG]
- Using already Existing Slice: It is also be allowed to create a slice from the given slice. For creating a slice from the given slice first you need to specify the lower and upper bound, which means slice can take elements from the given slice starting from the lower bound to the upper bound. It does not include the elements above from the upper bound. As shown in the below example:
Syntax:
slice_name[low:high]
This syntax will return a new slice.
Note: The default value of the lower bound is 0 and the default value of the upper bound is the total number of the elements present in the given slice.
Example:
Go
// Golang program to illustrate how to // create slices from the slice package main import "fmt" func main() { // Creating s slice oRignAl_slice := []int{ 90 , 60 , 40 , 50 , 34 , 49 , 30 } // Creating slices from the given slice var my_slice_1 = oRignAl_slice[ 1 : 5 ] my_slice_2 := oRignAl_slice[ 0 :] my_slice_3 := oRignAl_slice[: 6 ] my_slice_4 := oRignAl_slice[:] my_slice_5 := my_slice_3[ 2 : 4 ] // Display the result fmt.Println( "Original Slice:" , oRignAl_slice) fmt.Println( "New Slice 1:" , my_slice_1) fmt.Println( "New Slice 2:" , my_slice_2) fmt.Println( "New Slice 3:" , my_slice_3) fmt.Println( "New Slice 4:" , my_slice_4) fmt.Println( "New Slice 5:" , my_slice_5) } |
Output:
Original Slice: [90 60 40 50 34 49 30] New Slice 1: [60 40 50 34] New Slice 2: [90 60 40 50 34 49 30] New Slice 3: [90 60 40 50 34 49] New Slice 4: [90 60 40 50 34 49 30] New Slice 5: [40 50]
Using make() function: You can also create a slice using the make() function which is provided by the go library. This function takes three parameters, i.e, type, length, and capacity. Here, capacity value is optional. It assigns an underlying array with a size that is equal to the given capacity and returns a slice which refers to the underlying array. Generally, make() function is used to create an empty slice. Here, empty slices are those slices that contain an empty array reference.
Syntax:
func make([]T, len, cap) []T
Example:
Go
// Go program to illustrate how to create slices // Using make function package main import "fmt" func main() { // Creating an array of size 7 // and slice this array till 4 // and return the reference of the slice // Using make function var my_slice_1 = make([]int, 4 , 7 ) fmt.Printf( "Slice 1 = %v, \nlength = %d, \ncapacity = %d\n" , my_slice_1, len(my_slice_1), cap(my_slice_1)) // Creating another array of size 7 // and return the reference of the slice // Using make function var my_slice_2 = make([]int, 7 ) fmt.Printf( "Slice 2 = %v, \nlength = %d, \ncapacity = %d\n" , my_slice_2, len(my_slice_2), cap(my_slice_2)) } |
Output:
Slice 1 = [0 0 0 0], length = 4, capacity = 7 Slice 2 = [0 0 0 0 0 0 0], length = 7, capacity = 7
How to iterate over a slice?
You can iterate over slice using the following ways:
- Using for loop: It is the simplest way to iterate slice as shown in the below example:
Example:
Go
// Golang program to illustrate the // iterating over a slice using // for loop package main import "fmt" func main() { // Creating a slice myslice := [] string { "This" , "is" , "the" , "tutorial" , "of" , "Go" , "language" } // Iterate using for loop for e := 0 ; e < len(myslice); e++ { fmt.Println(myslice[e]) } } |
Output:
This is the tutorial of Go language
Using range in for loop: It is allowed to iterate over a slice using range in the for loop. Using range in the for loop, you can get the index and the element value as shown in the example:
Example:
Go
// Golang program to illustrate the iterating // over a slice using range in for loop package main import "fmt" func main() { // Creating a slice myslice := [] string { "This" , "is" , "the" , "tutorial" , "of" , "Go" , "language" } // Iterate slice // using range in for loop for index, ele := range myslice { fmt.Printf( "Index = %d and element = %s\n" , index+ 3 , ele) } } |
Output:
Index = 3 and element = This Index = 4 and element = is Index = 5 and element = the Index = 6 and element = tutorial Index = 7 and element = of Index = 8 and element = Go Index = 9 and element = language
Using a blank identifier in for loop: In the range for loop, if you don’t want to get the index value of the elements then you can use blank space(_) in place of index variable as shown in the below example:
Example:
Go
// Golang program to illustrate the iterating over // a slice using range in for loop without an index package main import "fmt" func main() { // Creating a slice myslice := [] string { "This" , "is" , "the" , "tutorial" , "of" , "Go" , "language" } // Iterate slice // using range in for loop // without index for _, ele := range myslice { fmt.Printf( "Element = %s\n" , ele) } } |
Output:
Element = This Element = is Element = the Element = tutorial Element = of Element = Go Element = language
Important points about Slice
Zero value slice: In Go language, you are allowed to create a nil slice that does not contain any element in it. So the capacity and the length of this slice is 0. Nil slice does not contain an array reference as shown in the below example:
Example:
Go
// Go program to illustrate a zero value slice package main import "fmt" func main() { // Creating a zero value slice var myslice [] string fmt.Printf( "Length = %d\n" , len(myslice)) fmt.Printf( "Capacity = %d " , cap(myslice)) } |
Output:
Length = 0 Capacity = 0
Modifying Slice: As we already know that slice is a reference type it can refer an underlying array. So if we change some elements in the slice, then the changes should also take place in the referenced array. Or in other words, if you made any changes in the slice, then it will also reflect in the array as shown in the below example:
Example:
Go
// Golang program to illustrate // how to modify the slice package main import "fmt" func main() { // Creating a zero value slice arr := [ 6 ]int{ 55 , 66 , 77 , 88 , 99 , 22 } slc := arr[ 0 : 4 ] // Before modifying fmt.Println( "Original_Array: " , arr) fmt.Println( "Original_Slice: " , slc) // After modification slc[ 0 ] = 100 slc[ 1 ] = 1000 slc[ 2 ] = 1000 fmt.Println( "\nNew_Array: " , arr) fmt.Println( "New_Slice: " , slc) } |
Output:
Original_Array: [55 66 77 88 99 22] Original_Slice: [55 66 77 88] New_Array: [100 1000 1000 88 99 22] New_Slice: [100 1000 1000 88]
Comparison of Slice: In Slice, you can only use == operator to check the given slice is nill or not. If you try to compare two slices with the help of == operator then it will give you an error as shown in the below example:
Example:
Go
// Golang program to check if // the slice is nil or not package main import "fmt" func main() { // creating slices s1 := []int{ 12 , 34 , 56 } var s2 []int // If you try to run this commented // code compiler will give an error /*s3:= []int{23, 45, 66} fmt.Println(s1==s3) */ // Checking if the given slice is nil or not fmt.Println(s1 == nil) fmt.Println(s2 == nil) } |
Output:
false true
Note: If you want to compare two slices, then use range for loop to match each element or you can use DeepEqual function.
Multi-Dimensional Slice: Multi-dimensional slice are just like the multidimensional array, except that slice does not contain the size.
Example:
Go
// Go program to illustrate the multi-dimensional slice package main import "fmt" func main() { // Creating multi-dimensional slice s1 := [][]int{{ 12 , 34 }, { 56 , 47 }, { 29 , 40 }, { 46 , 78 }, } // Accessing multi-dimensional slice fmt.Println( "Slice 1 : " , s1) // Creating multi-dimensional slice s2 := [][] string { [] string { "Geeks" , "for" }, [] string { "Geeks" , "GFG" }, [] string { "gfg" , "geek" }, } // Accessing multi-dimensional slice fmt.Println( "Slice 2 : " , s2) } |
Output:
Slice 1 : [[12 34] [56 47] [29 40] [46 78]] Slice 2 : [[Geeks for] [Geeks GFG] [gfg geek]]
Sorting of Slice: In Go language, you are allowed to sort the elements present in the slice. The standard library of Go language provides the sort package which contains different types of sorting methods for sorting the slice of ints, float64s, and strings. These functions always sort the elements available is slice in ascending order.
Example:
Go
// Go program to illustrate how to sort // the elements present in the slice package main import ( "fmt" "sort" ) func main() { // Creating Slice slc1 := [] string { "Python" , "Java" , "C#" , "Go" , "Ruby" } slc2 := []int{ 45 , 67 , 23 , 90 , 33 , 21 , 56 , 78 , 89 } fmt.Println( "Before sorting:" ) fmt.Println( "Slice 1: " , slc1) fmt.Println( "Slice 2: " , slc2) // Performing sort operation on the // slice using sort function sort.Strings(slc1) sort.Ints(slc2) fmt.Println( "\nAfter sorting:" ) fmt.Println( "Slice 1: " , slc1) fmt.Println( "Slice 2: " , slc2) } |
Output:
Before sorting: Slice 1: [Python Java C# Go Ruby] Slice 2: [45 67 23 90 33 21 56 78 89] After sorting: Slice 1: [C# Go Java Python Ruby] Slice 2: [21 23 33 45 56 67 78 89 90]