Keyed items in golang array initialization
Asked Answered
V

3

11

In a pub quiz by Dave Cheney I came across the following construct:

a := [...]int{5, 4: 1, 0, 2: 3, 2, 1: 4}
fmt.Println(a)

>> [5 4 3 2 1 0]

(Playground Link)

It seems you can use keys in the initialization fields of an array (4: 1, 0 means set element at index 4 to 1, element at index 5 to 0). I have never seen something like this before. What is its use case? Why not set the particular index directly?

Viewy answered 30/3, 2016 at 7:35 Comment(2)
Ok, so spare arrays. Has anybody used/seen this in the wild? Seems like a good thing on paper, but not in practice (except for pub quizzes of course).Viewy
since when is this syntax? never heard of this before XDNannienanning
N
17

In composite literals the key (index in case of array and slice literals) can be optionally provided.

For array and slice literals the following rules apply:

  • Each element has an associated integer index marking its position in the array.
  • An element with a key uses the key as its index; the key must be a constant integer expression.
  • An element without a key uses the previous element's index plus one. If the first element has no key, its index is zero.

Elements get the zero value of the element type whose value is not specified.

You can use this to:

  • more compactly initialize arrays and slices if the array/slice has many zero values and just a few non-zero values

  • skip ("jump over") contiguous parts when enumerating elements, and the skipped elements will be initialized with the zero values

  • specify the first couple of elements, and still specify the length (max index + 1) you want the array/slice to have:

      a := []int{10, 20, 30, 99:0} // Specify first 3 elements and set length to 100
    

The spec also contains an example: create an array which tells if a character is a vowel. This is a very compact and talkative way to initialize the array:

// vowels[ch] is true if ch is a vowel
vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true}

Another example: let's create a slice which tells if a day is weekend; Monday being 0, Tuesday being 1, ... and Sunday being 6:

weekend := []bool{5: true, 6: true} // The rest will be false

Or even better, you can even omit the 2nd index (6) as it will be implicitly 6 (previous +1):

weekend := []bool{5: true, true} // The rest will be false
Nickelson answered 30/3, 2016 at 7:57 Comment(0)
F
4

If your array indices are sparse, it's shorter than doing {1,0,0,0,0,2,0,0,0,0,3} etc, and it's shorter than multiple assignment lines, so I'm guessing that's the use case.

I've never seen this syntax used before anywhere.

Fabiano answered 30/3, 2016 at 7:43 Comment(2)
You were first, but I will accept icza's answer since it is more comprehensive. You have my upvote though.Viewy
@Viewy it's cool, icza's answers are always comprehensive and educational, and indeed he gave a much better answer.Fabiano
E
1

This can be useful when declaring and initializing arrays at the same time, especially globals that would otherwise need an init function to do something like this (Saturday and Sunday default to false)

var businessDays = [7]bool{
  time.Monday: true,
  time.Tuesday: true,
  time.Wednesday: true,
  time.Thursday: true,
  time.Friday: true,
}
Ed answered 14/7, 2023 at 14:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.