Slice literals

October 5, 2023

ReminderMonday I’ll be building a Go web server during my weekly live stream, following boot.dev’s “Learn Web Servers” course. I hope you can join me

Composite literals

A slice literal describes the entire underlying array literal. Thus the length and capacity of a slice literal are the maximum element index plus one. A slice literal has the form

``````[]T{x1, x2, … xn}
``````

and is shorthand for a slice operation applied to an array:

``````tmp := [n]T{x1, x2, … xn}
tmp[0 : n]
``````

If you recall from our earlier discussion of slices, a slice can be considered a “view” into a backing array. What the spec is telling us here is that a slice literal creates a backing array of the same length.

This has implications if you know you’ll be adding elements to your slice. When you grow a slice beyond the size of the backing array, a new backing array must be created, and this can have performance and memory usage implications. So is there a work-around? There is!

Let’s consider an example:

``````func dealPokerHand() []string {
result := []string{} // Slice literal, creates a backing array with length 0
for i := 0; i < 5; i++ {
card := getRandomCard()
result = append(result, card)
}
return result
}
``````

In this example, we create a slice of length 0, then we append to it 5 times, until we have a complete poker hand. This means there are up to 5 new memory allocations, as the new appended slice outgrows the backing array. (It may be fewer than 5 allocations, as the implementation may choose to grow the backing array by more than needed for the immediate allocation. The default Go implementation does this, but it’s an implementation optimization, not part of the spec.)

We can improve this situation by not using a slice literal, and instead construting our result slice with the builtin `make` function:

``````func dealPokerHand() []string {
result := make([]string, 0, 5) // result is has length 0, but the backing array has length 5
for i := 0; i < 5; i++ {
card := getRandomCard()
result = append(result, card)
}
return result
}
``````

Quotes from The Go Programming Language Specification Version of August 2, 2023