Welcome To Golang By Example

Append function in Go (Golang)

go builtin package provides an append function that can be used to append to a slice at the end. Below is the signature of this function

func append(slice []Type, elems ...Type) []Type

The first argument is the slice itself. The second is the variable number of arguments which is

elems ...Type

‘…’ operator is the variadic syntax. So basically …Type means that the append function can accept a variable number of arguments of type Type. Below is the way for using this function. In the below code, we are appending 4 to a slice which has two elements. It appends at the end and returns the original slice. That is why we are collecting results again in numbers variable. It is also ok to assign the result to some other variable.

numbers := []int{1,2}
numbers := append(numbers, 4) //Slice will become [1, 2, 3, 4]

It is also ok to append many number of elements because the second argument is the variadic argument.

numbers := []int{1,2}
numbers := append(numbers, 3, 4, 5) //Slice will become [1, 2, 3, 4, 5]

This function in background increases the length and capacity of the slice. There are two cases

In this case, on using the append function,  the length of the slice will be increased  by one without any change in its capacity. Let’s see a example

package main

import "fmt"

func main() {
    numbers := make([]int, 3, 5)
    numbers[0] = 1
    numbers[1] = 2
    numbers[2] = 3
    fmt.Printf("numbers=%v\n", numbers)
    fmt.Printf("length=%d\n", len(numbers))
    fmt.Printf("capacity=%d\n", cap(numbers))

    //Append number 4
    numbers = append(numbers, 4)
    fmt.Println("\nAppend Number 4")
    fmt.Printf("numbers=%v\n", numbers)
    fmt.Printf("length=%d\n", len(numbers))
    fmt.Printf("capacity=%d\n", cap(numbers))

    //Append number 5
    numbers = append(numbers, 4)
    fmt.Println("\nAppend Number 5")
    fmt.Printf("numbers=%v\n", numbers)
    fmt.Printf("length=%d\n", len(numbers))
    fmt.Printf("capacity=%d\n", cap(numbers))
}

Output

numbers=[1 2 3]
length=3
capacity=5

Append Number 4
numbers=[1 2 3 4]
length=4
capacity=5

Append Number 5
numbers=[1 2 3 4 4]
length=5
capacity=5

Capacity in all cases doesn’t changes and it is 5 while length increases by 1.

In this case since there is no more capacity, so no new elements can be accommodated.  So in this case under the hood an array of double the capacity will be allocated. The current array pointed by the  slice will be copied to that new array. Now the slice will starting pointing to this new array. Hence the capacity will be doubled and length will be increased by 1. Let’s see a example

package main

import "fmt"

func main() {
    numbers := make([]int, 3, 3)
    numbers[0] = 1
    numbers[1] = 2
    numbers[2] = 3

    fmt.Printf("numbers=%v\n", numbers)
    fmt.Printf("length=%d\n", len(numbers))
    fmt.Printf("capacity=%d\n", cap(numbers))

    //Append number 4
    numbers = append(numbers, 4)
    fmt.Println("\nAppend Number 4")
    fmt.Printf("numbers=%v\n", numbers)
    fmt.Printf("length=%d\n", len(numbers))
    fmt.Printf("capacity=%d\n", cap(numbers))
}

Output

numbers=[1 2 3]
length=3
capacity=3

Append Number 4
numbers=[1 2 3 4]
length=4
capacity=6

Notice in the above example that the capacity is doubled.

It is also possible to append one slice to another slice. Below is the format for that.

res := append(slice1, slice2...)

Notice ‘…’ after the second slice. ‘…’ is the operator which means that the argument is a variadic parameter. Meaning that during run time slice2 will be expanded to its individual elements which are passed as multiple arguments to the append function.

package main

import "fmt"

func main() {
    numbers1 := []int{1, 2}
    numbers2 := []int{3, 4}
    numbers := append(numbers1, numbers2...)
    fmt.Printf("numbers=%v\n", numbers)
    fmt.Printf("length=%d\n", len(numbers))
    fmt.Printf("capacity=%d\n", cap(numbers))
}

Output

numbers=[1 2 3 4]
length=4
capacity=4

append function for string

A string in go is nothing but a sequence of bytes. Hence it is legal to append a string to a slice of bytes. Below is the program for that. Notice the ‘…’ at then end of the string

package main

import "fmt"

func main() {
    sample := "Hello"
    suffix := "World"

    result := append([]byte(sample), suffix...)
    fmt.Printf("sample: %s\n", string(result))
}

Output

sample: HelloWorld