array
Arrays in Go are fixed size. If you want similar functionality to JavaScript/TypeScript arrays, you want to use slices.
Arrays
Section titled “Arrays”As said they are fixed size. This means that you cannot change the size of an array after it is created. You can only change the values inside the array.
var a [5]int // array of 5 integersvar b [5]int = [5]int{1, 2, 3, 4, 5} // array of 5 integers with valuesvar c = [5]int{1, 2, 3, 4, 5} // array of 5 integers with valuesvar d = [...]int{1, 2, 3, 4, 5} // array of 5 integers with values and size inferredAs always if the type can be inferred from the right side, you can omit it on the left side.
All of them declare a fixed array of 5 integers.
Slices
Section titled “Slices”This is the type that you want to use if you want dynamic arrays.
var a []int // slice of integersvar b []int = []int{1, 2, 3, 4, 5} // slice of integers with valuesvar c = []int{1, 2, 3, 4, 5} // slice of integers with valuesSlices have 2 important properties:
- Length: The number of current elements in the slice.
- Capacity: The maximum number of elements that can be stored in the slice before it needs to be resized.
To get the length and capacity of a slice you can use the built in len and cap functions:
var a = make([]int, 5, 10) // slice of 5 integers with capacity of 10fmt.Println(len(a)) // Output: 5fmt.Println(cap(a)) // Output: 10While Go automatically resizes slices when needed, this can sometimes be inefficient as it needs to allocate new memory, copy it etc.
For use cases where performance is critical and you want more control on when slices are resized, you can preallocate a slice with a specific length and capacity via the make function:
var a = make([]int, 5) // slice of 5 integersvar b = make([]int, 5, 10) // slice of 5 integers with capacity of 10The individual elements of the slice will be initialized to the zero value of the type. In this case, 0 for integers.
: operator
Section titled “: operator”You can use the : operator to quickly create a slice from an array or another slice:
var a = [5]int{1, 2, 3, 4, 5} // array of 5 integersvar b = a[1:3] // slice of array a from index 1 to 3 (exclusive)fmt.Println(b) // Output: [2 3]The first number is the starting index (inclusive) and the second number is the ending index (exclusive).
However you can also omit the first or second number to indicate the start or end of the slice.
Here’s how to get the first 3 elements of an array:
var a = [5]int{1, 2, 3, 4, 5} // array of 5 integersvar b = a[:3] // slice of array a from index 0 to 3 (exclusive)fmt.Println(b) // Output: [1 2 3]And here’s how to omit the first 3 elements of an array:
var a = [5]int{1, 2, 3, 4, 5} // array of 5 integersvar b = a[3:] // slice of array a from index 3 to endfmt.Println(b) // Output: [4 5]You can also use the : operator to create a slice from another slice.
Appending elements
Section titled “Appending elements”The append function is used to add elements to a slice:
var a = []int{1, 2, 3} // slice of integersa = append(a, 4) // append 4 to slice afmt.Println(a) // Output: [1 2 3 4]You can also append multiple elements at once:
var a = []int{1, 2, 3} // slice of integersa = append(a, 4, 5, 6) // append 4, 5, 6fmt.Println(a) // Output: [1 2 3 4 5 6]Modifying elements
Section titled “Modifying elements”This will work fine:
var a = []int{1, 2, 3} // slice of integersa[0] = 10 // modify first elementfmt.Println(a) // Output: [10 2 3]This will panic, even though capacity is 5 and we try to modify the 4th element:
It’s good practice to always check the length of the slice before modifying it, like:
var a = []int{1, 2, 3} // slice of integersif len(a) > 3 { a[3] = 10 // modify fourth element} else { fmt.Println("Slice is too short")}This will print Slice is too short and not panic.
Removing elements
Section titled “Removing elements”Removing elements is done by using the append function and slicing via :. Here’s how to remove the third element from a slice:
var a = []int{1, 2, 3, 4, 5} // slice of integersa = append(a[:2], a[3:]...) // remove third elementfmt.Println(a) // Output: [1 2 4 5]a[:2] creates a new slice with the first two elements and a[3:] creates a new slice with all elements after the third element. The ... operator is used to “spread” the elements of the slice into the append function.
Clearing a slice
Section titled “Clearing a slice”To clear a slice, you can simply set its length to 0:
var a = []int{1, 2, 3, 4, 5} // slice of integersa = a[:0] // clear slicefmt.Println(a) // Output: []This will retain the underlying array (capacity) but set the length to 0. Useful if you want to reuse the slice without allocating new memory.
To completely clear the slice and free the memory, you can set it to nil:
var a = []int{1, 2, 3, 4, 5} // slice of integersa = nil // clear slicefmt.Println(a) // Output: []This will set the slice to nil and free the memory used by the underlying array.
Copying a slice
Section titled “Copying a slice”To copy a slice, you can use the built-in copy function:
var a = []int{1, 2, 3, 4, 5} // slice of integersvar b = make([]int, len(a)) // create a new slice with the same lengthcopy(b, a) // copy slice a to slice bfmt.Println(b) // Output: [1 2 3 4 5]