在 Go 语言中要初始化一个数组可有很多种方式,可以直接指定长度不指定元素var arr [5]int,也可以显示初始化数组指定长度并赋值arr := [5]int{1, 2, 3, 4, 5},还可以按索引指定部分索引的值arr := [5]int{0: 10, 3: 40}。
但是刚刚刷到一道面试题,题目是这样的:
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:编译失败
当我看到[...]int{}这个写法后,总觉得这个语法是错误的,但又不敢肯定。
充满好奇心的我,立马打开编辑器粘贴上这段代码,发现编辑器并没有报语法错误,然后就go run运行了一下,果然它输出了:100。
难道我真是第一次见这种写法吗?但我真的是对它似曾相识啊。
我想起来了,这就是让编译器自动推断长度的初始化数组的一种方式。
m := [...]int{1, 2, 3, 4, 5}
fmt.Printf("Length: %d\n", len(m)) // 输出: Length: 5
如果这样写,我一定见过。在 Go 语言中可以使用...标记数组长度,编译器会自动根据数组的元素推断数组的长度。
让我陌生的可能是它的索引是单引号字母'a'这种格式,咋一看还以为是初始化map呢。
在前面的文章中我有分享go语言中的rune类型,没错!单引号字符就是rune类型,它的本质是int32,就是数字,所以它可以作为数组的索引,那要推断数组的长度,就只需要找到它的最大索引,然后 +1 就可以了。
那么,这个数组的最大索引就是'c',它的ASCII值是99,其实也可直接转int32的值:fmt.Println(int32('c')),由于数组的索引是从0开始的,所以m的长度就是100。
总结一下,这个面试题涉及三个知识点:
- 使用
...让编译器自动推断数组长度 - 使用
索引初始化数组的部分元素 - 单引号
'包裹的字符rune类型的本质
回想一下,做了这么多Go的项目,像上面这种完整的用法几乎很少被用到,但是面试题考察的是知识点,可以不用但不能不知道。
学以致用,融汇贯通,不断的充实自己,才能让自己在工作中处理问题时游刃有余。