I recently asked the following quiz question on this list, as well as on social media.
What does the following code print?
var hmm = [...]int{1, 2, 3, 12: 9, 8: 3}
fmt.Println(len(hmm))
On social media, I provided the following options:
- 5
- 7
- 13
- Doesn’t compile
And now the results are in! I got a total of 428 responses across LinkedIn, Twitter, and Mastodon:
The good news is: The majority are right! 13 is the correct answer. But why?
That’s what I’ll explain today.
(As an aside, the second most popular answer, Doesn’t compile is how I probably would have answered a week ago, too.)
First off, let’s examine [...]
. This should be familiar to anyone who’s a regular reader of my daily list, as we just discussed this on Monday. But here’s a refresher:
The notation
...
specifies an array length equal to the maximum element index plus one.
— The Go Spec
So from this we can deduce that we’re defining a variable of array type (not a slice, as was often assumed in some of the comments I received). This means it will have a fixed length, and from the quote above, that lenght is defined as equal to the maximum element index, plus one.
Which takes us to the next potentially confusing bit:
This code snippet mixes keyed and unkeyed elements in the declaration. The first three elements, 1, 2, 3
are pretty straight forward, and probably what you’re accustomed to. The next two elements 12: 9, 8: 3
are keyed. Specifically, it’s saying that value 9
should go to index 12
, and value 3
should go to index 8
.
From this, we can conclude that the maximum element index is 12. Therefore, the length is that, plus one, or 13. Tada! 🎉
If we print the contents of the hmm
variable, we’ll also see a bit more about what actually happened. We created a sparsely-populated array:
[1 2 3 0 0 0 0 0 3 0 0 0 9]
Indexes 3, 4, 5, 6, 7, 9, 10, and 11 are unset, so default to the zero value (or 0
in this case).