Arrays / Slices
| Since: | Go 1.0(2012) |
|---|
Arrays are fixed-length sequences, while slices are variable-length sequences. In Go, slices are used in everyday programming due to their flexibility.
Syntax
// Array declaration (fixed-length)
var arr [3]int
arr := [3]int{10, 20, 30}
arr := [...]int{10, 20, 30} // Length inferred from elements
// Slice declaration (variable-length)
var s []int
s := []int{10, 20, 30}
s := make([]int, length) // Initialized with zero values
s := make([]int, length, capacity) // Specify length and capacity
// Slice operations
s = append(s, value) // Append an element to the end
s = append(s, otherSlice...) // Concatenate slices
dst := make([]int, len(src))
copy(dst, src) // Copy elements
s2 := s[start:end] // Sub-slice
Syntax List
| Function/Operation | Description |
|---|---|
| append(s, v...) | Appends elements to a slice. The capacity is automatically expanded if needed. |
| copy(dst, src) | Copies elements from src to dst. Returns the number of elements copied. |
| len(s) | Returns the current number of elements in a slice (or array). |
| cap(s) | Returns the capacity of a slice — the maximum number of elements it can hold without reallocation. |
| make([]T, len, cap) | Creates a slice with the specified type, length, and capacity. |
| s[i:j] | Creates a sub-slice from index i up to (but not including) j. Shares the underlying memory with the original slice. |
Sample Code
sample_array_slice.go
package main
import "fmt"
func main() {
// Array (fixed-length)
arr := [3]string{"Son Goku", "Vegeta", "Krillin"}
fmt.Println(arr[0], len(arr)) // Son Goku 3
// Slice (variable-length)
fighters := []string{"Son Goku", "Vegeta"}
fmt.Printf("len=%d cap=%d\n", len(fighters), cap(fighters))
// Append elements with append
fighters = append(fighters, "Krillin", "Piccolo")
fmt.Println(fighters)
// Copy a slice (independent memory)
copied := make([]string, len(fighters))
copy(copied, fighters)
copied[0] = "Bulma"
fmt.Println(fighters[0]) // Son Goku (unchanged)
fmt.Println(copied[0]) // Bulma
// Sub-slice
part := fighters[1:3]
fmt.Println(part) // [Vegeta Krillin]
// Pre-allocate capacity with make (improves performance)
nums := make([]int, 0, 10)
for i := 0; i < 5; i++ {
nums = append(nums, i*2)
}
fmt.Println(nums)
}
This produces the following output:
go run array_slice.go Son Goku 3 len=2 cap=2 [Son Goku Vegeta Krillin Piccolo] Son Goku Bulma [Vegeta Krillin] [0 2 4 6 8]
Notes
The key difference between arrays and slices is whether the length is part of the type. [3]int and [4]int are distinct types, whereas slices have the same type regardless of length. In practice, you will almost always use slices.
A sub-slice (such as s[1:3]) shares the underlying memory with the original slice. Changes to a sub-slice also affect the original, so always use copy() when you need an independent copy.
If you know in advance that you will be appending many elements, pre-allocating capacity with make([]T, 0, capacity) reduces repeated memory reallocations and improves performance. Like maps, slices are reference types — keep this in mind when passing them around.
If you find any errors or copyright issues, please contact us.