Golang Arrays and Slices – Built-in Functions

Share this blog with others!

In this blog, we will take a look at Arrays and Slices in Golang or The Go Programming Language.

Let’s see what we will be learning.

Arrays and Slices in Golang or Go Language:

  • Creation of Arrays and Slices
  • Built-in functions in Arrays and Slices
  • How to work with Arrays and Slices

Before starting this topic must read the previous topics:

The need for Arrays in Language

Golang Arrays | Source – Divyanshu Shekhar

Arrays are containers of values in a programming language, it gives continuous memory blocks to the variables and it’s easy to access.

Let’s assume that an Integer value takes 4 bytes of memory. So in order to store many integer values in contiguous memory blocks and the memory will be allocated with a difference of 4 bytes.

We can access any element in the array using the index and one important thing to notice here is the index starts with 0 and not 1.

Arrays have a constant look up time.

Example from the Picture above (name of the Array arr):

fmt.Println(arr[0])
fmt.Println(arr[1])
fmt.Println(arr[2])
fmt.Println(arr[3])

Output:

15
24
30
45

Golang Make Array

Golang Array Creation | Source – Divyanshu Shekhar
package main

import (
	"fmt"
)

func main() {

	var arr = [8]int{15, 24, 30, 45, 56, 12, 34, 19}
	fmt.Println(arr)

}

Output:

[15 24 30 45 56 12 34 19]

If you look at the program or the Array creation Image, you will find that we have declared the size of the array two times, which is unnecessary.

Another way to declare arrays when you want to declare it with values is:

Golang Arrays
Golang Array Shorthand
package main

import (
	"fmt"
)

func main() {

	var arr = [...]int{15, 24, 30, 45, 56, 12, 34, 19}
	fmt.Println(arr)

}

Output: – Same Output as above.

Golang Arrays Declaration

var arr [5]string

package main

import (
	"fmt"
)

func main() {

	var names [5]string
	fmt.Println("Names ", names)

}

Output:

Names [ ]

Golang Arrays Mutable

Earlier we had declared empty array and we can now fill it with values using indexes, this makes arrays mutable.

package main

import (
	"fmt"
)

func main() {

	var names [5]string
	names[0] = "Divyanshu Shekhar"
	fmt.Println("Names ", names)

}

Output:

Names [Divyanshu Shekhar ]

We need not to fill the values continuously. Order doesn’t matter while filling up the values.

Example:

package main

import (
	"fmt"
)

func main() {

	var names [5]string
	names[0] = "Divyanshu Shekhar"
	names[2] = "Shubham Ranjan"
	names[1] = "Arpit Sahu"
	fmt.Println("Names ", names)

}

Output:

Names [Divyanshu Shekhar Arpit Sahu Shubham Ranjan ]

Golang Arrays Built-in Functions

Let’s see Built in Functions in Golang Arrays.

Golang Array length

len(<array_name>)

package main

import (
	"fmt"
)

func main() {

	var names [5]string
	names[0] = "Divyanshu Shekhar"
	names[2] = "Shubham Ranjan"
	names[1] = "Arpit Sahu"
	fmt.Println("Length of names Array: ", len(names))

}

Output:

Length of names Array: 5

Golang 2D Arrays

package main

import (
	"fmt"
)

func main() {

	var matrix [3][3]int = [3][3]int{[3]int{1, 2, 3}, [3]int{4, 5, 6}, [3]int{7, 8, 9}}
	fmt.Println("2D Array:", matrix)
	fmt.Println("Length of 2D Array:", len(matrix))

}

2D Array in Golang can also be filled using indexes.

	matrix[0] = [3]int{1, 2, 3}
	matrix[1] = [3]int{4, 5, 6}
	matrix[2] = [3]int{7, 8, 9}

Output:

2D Array: [[1 2 3] [4 5 6] [7 8 9]]
Length of 2D Array: 3

Golang array copy

In other languages, arrays are considered as pointers that point to the memory block holding that specific value, but in Golang Arrays are considered as values.

When copying an array to another array in other languages like c/c++/python, the language used to pass a reference to the array, and any changes made in the copied array used to change the original array.

package main

import (
	"fmt"
)

func main() {

	var a = [...]int{15, 24, 30, 45, 56, 12, 34, 19}
	b := a
	a[1] = 100
	fmt.Println("a : ", a)
	fmt.Println("b : ", b)

}

Output:

a : [15 100 30 45 56 12 34 19]
b : [15 24 30 45 56 12 34 19]

But, In Golang as arrays are values it gets fully copied to another variable of array type, and any changes made in the copied array don’t reflect on the original array.

Golang Pointers

We can also pass the same array to the another array variable using pointers. We pass the memory address of the array to the next array and thus both the variables can access the same variable.

In this case any of the variable can potentially change the value in the array.

b := &a

package main

import (
	"fmt"
)

func main() {

	var a = [...]int{15, 24, 30, 45, 56, 12, 34, 19}
	b := &a
	a[1] = 100
	fmt.Println("a : ", a)
	fmt.Println("b : ", b)

}

Output:

a : [15 100 30 45 56 12 34 19]
b : &[15 100 30 45 56 12 34 19]

Golang Slices

a := []<datatype>{<values>}

Slices in Golang are almost the same as Arrays, the only difference is we had to pass size inside the square braces in an Array creation or three dots (…), but while slice creation we neither have to pass the size of the array nor three dots (…).

package main

import (
	"fmt"
)

func main() {

	var a = []int{15, 24, 30, 45, 56, 12, 34, 19}
	fmt.Printf("%v,%T", a, a)
	fmt.Println("Length of Slice a : ", len(a))
}

Output:

[15 24 30 45 56 12 34 19],[]int
Length of Slice a : 8

Golang Slice Capacity

var a = [8]int{15, 24, 30, 45, 56, 12, 34, 19}
fmt.Println("Capacity of Slice a : ", cap(a))

Output:

Capacity of Slice a : 8

Golang Slice Append

The append function takes the slice in which the values are to be appended.

package main

import (
	"fmt"
)

func main() {

	var a = []int{}
	a = append(a, 2, 3, 4, 5)
	fmt.Println(a)
	fmt.Println("Length of the array a: ", len(a))
	fmt.Println("Capacity of the array a: ", cap(a))

}

Output:

[2 3 4 5]
Length of the array a: 4
Capacity of the array a: 4

Golang Spread Operator

First take a look without spread operator.

var b = []int{2, 3, 4, 5, 6, 7, 8}
a = append(a, b)

Error:- cannot use b (type []int) as type int in append

Using Spread Operator

package main

import (
	"fmt"
)

func main() {

	var a = []int{}
	var b = []int{2, 3, 4, 5, 6, 7, 8}
	a = append(a, b...)
	fmt.Println(a)
	fmt.Println("Length of the array a: ", len(a))
	fmt.Println("Capacity of the array a: ", cap(a))

}

Output:-

[2 3 4 5 6 7 8]
Length of the array a: 7
Capacity of the array a: 8

Append Function doesn’t work with Golang arrays

package main

import (
	"fmt"
)

func main() {

	var a = [...]int{}
	a = append(a, 2, 3, 4)
	fmt.Println(a)
	fmt.Println("Length of the array a: ", len(a))
	fmt.Println("Capacity of the array a: ", cap(a))

}

Error:- first argument to append must be slice; have [0]int

Golang Slice of Slices

These slicing operations can also be done on Arrays in Golang.

package main

import (
	"fmt"
)

func main() {

	var a = [8]int{15, 24, 30, 45, 56, 12, 34, 19}
	b := a[:]
	c := a[2:]
	d := a[:5]
	e := a[2:5]

	fmt.Println("b : ", b)
	fmt.Println("c : ", c)
	fmt.Println("d : ", d)
	fmt.Println("e : ", e)

}

1. a[:]

This will slice all the values of the array ‘a’.

2. a[2:]

This will start slicing from the second index and will slice all the way to end.

3. a[:5]

This will start slicing from the start and will last at the 4th index (Excluding 5th index).

4. a[2:5]

This will start slicing from the second index and will slice till the 4th index (Excluding the 5th index).

Golang Slicing

1. Slicing element from start

        var a = []int{1, 2, 3, 4, 5, 6, 7, 8}
        fmt.Println(a[1:])

Output: – [2 3 4 5 6 7 8]

2. Slicing element from end

	var a = []int{1, 2, 3, 4, 5, 6, 7, 8}
	fmt.Println(a[:len(a)-1])

Output:- [1 2 3 4 5 6 7]

3. Slicing element from middle

	var a = []int{1, 2, 3, 4, 5, 6, 7, 8}
	a = append(a[:2], a[5:]...)
	fmt.Println(a)

Output:- [1 2 6 7 8]

Golang Slice vs Array

1. Golang Slices Reference type

Do you remember copying of array discussed above?

When we used to initialize one array to another array, it used to get fully copied and any changes made in the copied array didn’t affect the original array.

But slices in Golang are reference types and it passes the memory location of the array and both the variables access the same array and can change the values of the array.

package main

import (
	"fmt"
)

func main() {
        // Slices in Golang
	var a = []int{15, 24, 30, 45, 56, 12, 34, 19}
	b := a
	a[1] = 100
	fmt.Println("a : ", a)
	fmt.Println("b : ", b)

}

Output:

a : [15 100 30 45 56 12 34 19]
b : [15 100 30 45 56 12 34 19]

Output:

b : [15 24 30 45 56 12 34 19]
c : [30 45 56 12 34 19]
d : [15 24 30 45 56]
e : [30 45 56]

Golang Slice Make

make(<type_object>, <length>,<capacity>)

package main

import (
	"fmt"
)

func main() {

	var a = make([]int, 5, 100)
	fmt.Println("a :", a)
	fmt.Println("Length of Slice a :", len(a))
	fmt.Println("Capacity of Slice a :", cap(a))

}

Output:

a : [0 0 0 0 0]
Length of Slice a : 5
Capacity of Slice a : 100

Golang Slices Make Function

When we don’t make slice using make function, we are not able to specify the capacity of the slice and the compiler takes the charge of increasing capacity of the slice in Golang.

package main

import (
	"fmt"
)

func main() {

	var a = []int{}
	fmt.Println(a)
	fmt.Println("Length of the array a: ", len(a))
	fmt.Println("Capacity of the array a: ", cap(a))
	for i := 0; i < 33; i++ {
		a = append(a, i)
		fmt.Println(a)
		fmt.Println("Length of the array a: ", len(a))
		fmt.Println("Capacity of the array a: ", cap(a))
	}

}

Output:-

[]
Length of the array a: 0
Capacity of the array a: 0
[0]
Length of the array a: 1
Capacity of the array a: 1
[0 1]
Length of the array a: 2
Capacity of the array a: 2
[0 1 2]
Length of the array a: 3
Capacity of the array a: 4
[0 1 2 3]
Length of the array a: 4
Capacity of the array a: 4
[0 1 2 3 4]
Length of the array a: 5
Capacity of the array a: 8
.
.
Length of the array a: 8
Capacity of the array a: 8
[0 1 2 3 4 5 6 7 8]
Length of the array a: 9
Capacity of the array a: 16
.
.
.
.
.
.
[0 1 2 3 …….. 12 13 14 15]
Length of the array a: 16
Capacity of the array a: 16
[0 1 2 3 ……. 12 13 14 15 16]
Length of the array a: 17
Capacity of the array a: 32
.
.
.
[0 1 2 3 4 5 6
[0 1 2 ……. 27 28 29 30 31]
Length of the array a: 32
Capacity of the array a: 32
[0 1 2 3 ……. 30 31 32]
Length of the array a: 33
Capacity of the array a: 64

We see a pattern in the increase of the capacity of the slice i.e each time the capacity is full it is multiplied by 2 and the capacity is increased.

When the value of the variable ‘i’ increases to 32, the length of the slice becomes 33 which is greater than the previous capacity of the slice and thus multiplies by 2 (32 x 2), and the capacity increases to 64.

This can occupy unnecessary memory in our program, so it’s better to take control of your memory by making slices using make function. You can pass the capacity of the slice and this will lead to memory management in your program.

Read Why Golang is called the future of server-side language?

Learn more about Arrays and Slices in Golang from Official Documentation.

0 0 votes
Article Rating

Share this blog with others!
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
Scroll to Top