看到 [...]int{'a': 1, 'b': 2, 'c': 3} 这种写法,很多人第一眼都会误判成语法有问题,或者把它看成了某种 map 初始化。真正容易混淆的地方,其实不在数组本身,而在 ...、按索引赋值,以及单引号字符这三层语义叠在了一起。下面就按这道题的执行结果,把它为什么能编译、为什么长度是 100,以及它到底考了哪些 Go 基础,一次讲清楚。
题目代码为什么会输出 100
先看题目原始代码:
package main
import (
"fmt"
)
func main() {
m := [...]int{
'a': 1,
'b': 2,
'c': 3,
}
m['a'] = 3
fmt.Println(len(m))
}
题目问的是这段代码会输出什么。选项通常写成:
A:3;B:4;C:100;D:编译失败
实际运行后,结果是 100。关键原因是:这不是 map,而是数组;'a'、'b'、'c' 也不是字符串键,而是可以参与索引计算的字符常量。
`[...]int{}` 到底是什么语法
Go 初始化数组有几种常见写法:
var arr [5]int
arr := [5]int{1, 2, 3, 4, 5}
arr := [5]int{0: 10, 3: 40}
其中 [...]int{} 这一种,表示数组长度由编译器自动推断。也就是说,... 不是“任意长度”的意思,而是“根据初始化内容算出数组长度”。
例如:
m := [...]int{1, 2, 3, 4, 5}
fmt.Printf("Length: %dn", len(m)) // 输出: Length: 5
这里数组里有 5 个元素,所以长度就是 5。这个语法本身并不少见,只是很多人更常见的是按顺序写值,而不是和“按索引初始化”一起使用。
按索引初始化时,长度是怎么推断出来的
题目真正特别的地方,在于它不是顺序填值,而是这样写:

m := [...]int{
'a': 1,
'b': 2,
'c': 3,
}
这属于按索引初始化数组部分元素。对于这种写法,编译器推断长度时,不是看你写了几个键值对,而是看最大索引是多少,然后再加 1。
如果索引是 0 到 4,数组长度就是 5;如果最大索引是 99,那数组长度就是 100。因此这道题的核心,马上就变成了:'c' 到底对应多少。
为什么 `'a'` 可以当数组索引
很多人第一眼会觉得这里像 map,就是因为索引位置出现了单引号字符:

'a'
'b'
'c'
但在 Go 里,单引号包裹的字符是 rune。而 rune 的本质是 int32,也就是整数类型的别名语义表示。因此,它可以作为数组索引使用。
换句话说,这里并不是“用字符做特殊键”,而是“用字符对应的数值做索引”。例如可以直接验证:
fmt.Println(int32('c'))
'c' 的值是 99,所以这个数组里出现的最大索引就是 99。数组索引从 0 开始,最大索引为 99 时,数组长度自然就是 100。
这也解释了后面的语句为什么成立:
m['a'] = 3
这里本质上等价于把某个整数索引位置重新赋值,并不会改变数组长度,只是把原来索引 'a' 对应位置上的值从 1 改成了 3。
这道题实际考查的 3 个 Go 基础点
把整道题拆开看,核心其实只有三件事:
- 使用
...让编译器自动推断数组长度 - 使用索引形式初始化数组的部分元素
- 理解单引号字符是
rune,本质上是可参与索引计算的整数值
这类组合写法在日常项目里不算高频,完整地把这三种语法叠在一起更少见,所以陌生感很正常。但面试题往往就爱考这种“单点都见过,合起来容易看懵”的基础题。
因此,这道题最值得记住的不是答案 100 本身,而是判断顺序:先确认它是数组,再确认 ... 是长度推断,最后把 'c' 当作数值索引去算。顺着这条线看,结论就不会错。













