In the previous chapter, we discuss how to use
append function
in Golang.append is a built-in function which appends elements to the
end of a slice. If it has sufficient capacity, the destination is
resliced to accommodate the new elements. If it does not, a new
underlying array will be allocated. Append returns the updated slice. It
is therefore necessary to store the result of append, often in the
variable holding the slice itself.
The signature of append:
func append(slice []T, elements ...T) []T
whereTis a placeholder for any given type. You can’t actually write
a
function
in Go where the typeTis determined by the caller. That’s
whyappendis built in: it needs support from the compiler.

Example 1: Simple usage of append function
Here is an example of using append 1 or multiple elements to a slice:
package main
import "fmt"
func main() {
slice0 := []int{2, 5,13,15}
fmt.Println("slice 0:", slice0)
// append 1 element
fmt.Println("after the first append:", append(slice0, 4))
// append multiple elements
fmt.Println("after the second append:", append(slice0, 3, 5, 7))
}
Output
slice 0: [2 5 13 15]
after the first append: [2 5 13 15 4]
after the second append: [2 5 13 15 3 5 7]
Whatappenddoes is append the elements to the end of the slice and
return the result. The result needs to be returned because, as with our
hand-writtenAppend, the underlying array may change. You can see
that the original slice is not affected after the first append because
we do not assign return append value to the original slice.
Example 2: Update the slice itself after calling append function
In the example below, we will assign the return append value to the original slice:
package main
import "fmt"
func main() {
slice0 := []int{2, 5,13,15}
fmt.Println("slice 0:", slice0)
// append 1 element
slice0 = append(slice0, 4)
fmt.Println("after the first append:", slice0)
// append multiple elements
slice0 = append(slice0, 3, 5, 7)
fmt.Println("after the second append:", slice0)
}
Output:
slice 0: [2 5 13 15]
after the first append: [2 5 13 15 4]
after the second append: [2 5 13 15 4 3 5 7]
Example 3: Unintended side effects when using append function
In this example, we will first create an int slice:
firstSlice := []int{12, 6, 19, 98}
Do the following steps:
- Initialize a new slice (secondSlice) which contains the first three elements of the firstSlice (firstSlice[:3]) and appending 1 element to it.
- Initialize a new slice (thirdSlice) by appending 1 element to the firstSlice
secondSlice := append(firstSlice[:3], 59)
thirdSlice := append(firstSlice, 820)
Now we will print out these 3 slices:
package main
import "fmt"
func main() {
firstSlice := []int{12, 6, 19, 98}
secondSlice := append(firstSlice[:3], 59)
thirdSlice := append(firstSlice, 820)
fmt.Println("the first slice:", firstSlice)
fmt.Println("the second slice:", secondSlice)
fmt.Println("the third slice", thirdSlice)
}
Output:
the first slice: [12 6 19 59]
the second slice: [12 6 19 59]
the third slice [12 6 19 59 820]
The output of the secondSlice is easy to understand. But how about the firstSlice and thirdSlice? You may think that the firstSlice is not affected by the append function call. But why both firstSlice and thirdSlice are changed?
You must first understand the proper definition of a slice in order to
comprehend this behavior. Slices hold references to an underlying array,
and if you assign one slice to another, both refer to the same array.
The length of a slice may be changed as long as it still fits
within the limits of the underlying array; just assign it to a slice of
itself. Thecapacityof a slice, accessible by the built-in
functioncap, reports the maximum length the slice may assume.
In other words, the underlying array will not be assigned to new memory address if it can fit the additional element(s). In the case of there is insufficient capacity, a new array will be made. Now you can understand why the firstSlice is affected by the append function (because both firstSlice and secondSlice refer to 1 underlying array).
Summary
The idea of appending to a slice is so useful it’s captured by
theappend built-in function. We must return the slice afterwards
because, althoughAppendcan modify the elements ofslice, the slice
itself (the run-time data structure holding the pointer, length, and
capacity) is passed by
value.
References
https://pkg.go.dev/builtin#append
https://go.dev/doc/effective_go#append

![Golang slice append return value? [SOLVED]](/golang-slice-append-return/golang-append-slice.jpg)
