The built-in append is how you golang add to slice values: it appends zero or more elements of type E to a slice []E and returns a new slice header (often you assign back to the same variable). Searches like golang append, append golang, golang append to slice, golang slice append, go append, or go append to array all point here—remember Go’s arrays are fixed, so you usually append to a slice backed by an array. For variadic unpacking (...), see variadic functions in Go; for merging with uniqueness rules, see concatenate slices (unique); for removing items, see delete from slice.
Tested with Go 1.24 on Linux.
A slice is a small descriptor (pointer, length, capacity) over a backing array; append may grow capacity and move data when there is no room left.
golang append: one value or many
append(s, x1, x2, ...) returns []E with the new elements at the end. Always keep the return value:
package main
import "fmt"
func main() {
s := []int{1, 5}
s = append(s, 2)
s = append(s, 3, 5, 7)
fmt.Println(s)
}You should see [1 5 2 3 5 7].
golang append slice to slice (...)
To append all elements of another slice, spread the second slice with ... (same element type required):
package main
import "fmt"
func main() {
a := []string{"Hello", "world"}
b := []string{"from", "Go"}
out := append(a, b...)
fmt.Println(out)
}You should see [Hello world from Go]. Overlapping source and destination slices are allowed; append still does the right thing for the documented cases.
go append to array (via slicing)
You cannot change an array’s length, but you can append to a slice view of it:
package main
import "fmt"
func main() {
var arr [2]int
s := arr[:]
s = append(s, 9)
fmt.Println("slice:", s, "array:", arr)
}You should see slice: [0 0 9] and array: [0 0]. Once append grows past the array’s capacity, it allocates a new backing array, so the fixed-size arr no longer receives further elements—this is why growable buffers are usually []T from the start, not [n]T with append.
[]byte and string: special append rule
For []byte, you may append individual bytes or append the bytes of a string using ...:
package main
import "fmt"
func main() {
out := append([]byte("Hello "), "GoLinuxCloud!"...)
fmt.Println(string(out))
}You should see Hello GoLinuxCloud!.
Heterogeneous values with []any
A []any ([]interface{}) slice can hold mixed dynamic types; each append still adds values of concrete types:
package main
import (
"fmt"
"time"
)
func main() {
var v []any
v = append(v, 25, 3.14, "hello", time.Date(2026, 6, 17, 0, 0, 0, 0, time.UTC))
fmt.Println(len(v), v[0], v[2])
}You should see 4 25 hello (middle fields vary). For typed APIs, prefer structs or separate slices instead of []any unless you really need a dynamic bag.
Summary
append covers golang append, golang append to slice, and golang slice append patterns: pass new elements, or pass another slice with ... for golang append slice to slice. Treat go append to array as append to a slice view or use a slice from the start. For []byte, you can append string bytes with .... Always assign the result (s = append(s, x)) because the backing store may change. Pair this with the Go spec on append and copy and Slices intro blog.
References
- Appending and copying slices — Go spec
- Go slices: usage and internals
- Variadic functions
- Concatenate slices (unique)
- Delete elements from a slice

