在golang数组初始化中,键控项是什么?

11

在 Dave Cheney 的 pub quiz 中,我遇到了下面的结构:

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

>> [5 4 3 2 1 0]

(游乐场链接)

看起来你可以在数组的初始化字段中使用键(4: 1, 0表示将索引为4的元素设置为1,索引为5的元素设置为0)。我以前从未见过这样的写法。它有什么用途?为什么不直接设置特定的索引?


好的,那么让我们谈谈备用数组。有人在实际应用中使用或看到过吗?在理论上似乎是个好东西,但实际上并不是(当然除了酒吧智力竞赛)。 - RickyA
这个语法是从什么时候开始的?以前从来没有听说过XD。 - Kokizzu
3个回答

15
组合字面量中,键(在数组和切片字面量的情况下为索引)可以选择性地提供。
对于数组和切片字面量,应用以下规则:
- 每个元素都有一个相关联的整数索引,标记其在数组中的位置。 - 使用键的元素将其作为索引;键必须是常量整数表达式。 - 不使用键的元素使用先前元素的索引加一。如果第一个元素没有键,则其索引为零。
元素获得未指定值的元素类型的零值。
您可以使用此功能:
  • 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
    
该规范还包含一个示例:创建一个数组,告诉字符是否为元音字母。这是一种非常紧凑而富有表现力的初始化数组的方式:
// vowels[ch] is true if ch is a vowel
vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true}

另一个例子:让我们创建一个切片,告诉我们一天是否是周末;星期一为0,星期二为1,...星期日为6:
weekend := []bool{5: true, 6: true} // The rest will be false

甚至更好的是,您可以省略第二个索引(6),因为它会隐式地变成6(前一个+1):

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

2
如果您的数组索引是稀疏的,那么使用 {1,0,0,0,0,2,0,0,0,0,3} 等方式会更长,同时也比多个赋值语句更长,因此我猜测这就是使用情况。我之前从未在任何地方见过这种语法。

你先回答了,但我会选择 icza 的答案,因为它更全面。不过我会给你点赞的。 - RickyA
@RickyA,很酷,icza的回答总是全面而有教育意义的,他确实给出了更好的答案。 - Not_a_Golfer

1
这在同时声明和初始化数组时非常有用,尤其是全局变量,否则需要一个初始化函数来执行类似的操作(默认Saturday和Sunday为false)。
var businessDays = [7]bool{
  time.Monday: true,
  time.Tuesday: true,
  time.Wednesday: true,
  time.Thursday: true,
  time.Friday: true,
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接