在 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的项目,像上面这种完整的用法几乎很少被用到,但是面试题考察的是知识点,可以不用但不能不知道。

学以致用,融汇贯通,不断的充实自己,才能让自己在工作中处理问题时游刃有余。