Friday, November 22, 2024
Google search engine
HomeLanguagesGolangSlices in Golang

Slices in Golang

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]

RELATED ARTICLES

Most Popular

Recent Comments