In previous articles, we introduced some examples of working with slices in Golang. In today's post, I will introduce the best way to append anything (a slice, an element, or a string) to a slice.
Introduction to Golang append function
append:
The built-in functions append and copy assist in common slice operations. For both functions, the result is independent of whether the memory referenced by the arguments overlaps. The variadic function append appends zero or more values x to a slice s and returns the resulting slice of the same type as s. The core type of s must be a slice of type []E. The values x are passed to a parameter of type ...E and the respective parameter passing rules apply. As a special case, if the core type of s is []byte, append also accepts a second argument with core type bytestring followed by .... This form appends the bytes of the byte slice or string.
append(s S, x ...E) S // core type of S is []E
You can utilize a slice as a dynamic array by using the built-in append method. The function appends any number of elements to the end of a slice:
- If the underlying array has enough space, it is reused;
- if not, space is provided for a new underlying array, and the data is moved across.
Returning the modified slice from append.
The outcome of an append must therefore be stored, frequently in the variable containing the slice itself.
Here is an example of using append 1 or multiple elements to a slice:
package main
import "fmt"
func main() {
slice0 := []int{1, 5}
slice1 := append(slice0, 2) // append 1 element
slice2 := append(slice1, 3, 5, 7) // append multiple elements
fmt.Println("slice 0:", slice0)
fmt.Println("slice 1:", slice1)
fmt.Println("slice 2:", slice2)
}
Output:
slice 0: [1 5]
slice 1: [1 5 2]
slice 2: [1 5 2 3 5 7]
Example 1: Append one slice to another
You can concatenate two slices using the variadic function. Here is an example of append 2 slices:
package main
import "fmt"
func main() {
slice1 := []string{"Hello", "world", "this", "is", "Golinuxcloud"}
slice2 := []string{"Welcome", "to", "our", "page"}
slice3 := append(slice1, slice2...) //append 2 slice
slice4 := append(slice1[1:3], slice3[1:5]...) //append append overlapping slice
fmt.Println("slice 1:", slice1)
fmt.Println("slice 2:", slice2)
fmt.Println("slice 3:", slice3)
fmt.Println("slice 4:", slice4)
}
Output:
slice 1: [Hello world this is Golinuxcloud]
slice 2: [Welcome to our page]
slice 3: [Hello world this is Golinuxcloud Welcome to our page]
slice 4: [world this world this is Golinuxcloud]
Noted that:
- The
...
unpacks the second parameter. It will append the whole slice if we remove the three dots, which is invalid. - The append function does not care about the overlapping 2 slices
Example 2: Append multiple data types to slice
With the help of interface{} type, we can append multiple data types to 1 slice. Let's take a look at the code below to see how to do that:
package main
import (
"fmt"
"time"
)
func main() {
var intefaceSlice []interface{}
start := time.Now()
// append multiple data types
intefaceSlice = append(intefaceSlice, 25, 3.14, "hello", start)
fmt.Println("Multiple data types slice:", intefaceSlice)
}
Output:
Multiple data types slice: [25 3.14 hello 2022-10-28 16:22:25.719494643 +0700 +07 m=+0.000016962]
Example 3: Append a string to a byte slice
As a special case, Golang allows appending a string to a byte slice. Here is an example of appending a string to a byte slice and then print the returned byte slice as a string:
package main
import (
"fmt"
)
func main() {
specialSlice := append([]byte("Hello "), "GoLinuxCloud members!"...)
fmt.Println("special append slice in byte:", specialSlice)
fmt.Println("special append slice in string:", string(specialSlice[:]))
}
Output:
special append slice in byte: [72 101 108 108 111 32 71 111 76 105 110 117 120 67 108 111 117 100 32 109 101 109 98 101 114 115 33]
special append slice in string: Hello GoLinuxCloud members!
Summary
Since adding new elements to a slice is a typical practice, Go includes a built-in append
function. With the detailed examples shown below, I hope you can understand how to append an element or even a slice to another slice.append()
won't fail unless memory runs out. If the slice is kept around, the trash collector won't free memory. If it is quite large, it might be a problem.
References
https://go.dev/ref/spec#Appending_and_copying_slices
https://go.dev/blog/slices-intro