在 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
的项目,像上面这种完整的用法几乎很少被用到,但是面试题考察的是知识点,可以不用但不能不知道。
学以致用,融汇贯通,不断的充实自己,才能让自己在工作中处理问题时游刃有余。