数组基本上在除了python以外的各个编程语言里都是存在的。GoLang数组的特殊性在于语法上,这种写法,我这种长期写java和python的程序员就非常不习惯。但是不习惯也没办法,硬着头皮去适应吧。有很多语法点是我以前的编程经历里没有的,所以我一个个记下来。 数组声明

  以往写C、java之类的语言,数组定义的中括号是写在类型后面或变量名后面的。而现在要这样写了,也就是写在类型前面:

package main

import "fmt"

func main() {
	var q [3]int
	q = [3]int{1, 2, 3}
	fmt.Println(q)
}

字面量

  字面量的长度可以自动计算,但不是像java一样在方括号里不写长度,而是一种非常奇怪的语法,在方括号里写上三个点号。如下:

package main

import "fmt"

func main() {
	q := [...]int{1, 2, 3, 4, 5, 6, 7}
	fmt.Println(q, len(q))
}

长度与类型

  Go的数组还有个奇怪的地方,长度也是类型的一部分。长度为3的int数组和长度为4的int数组不是同一个类型。长度不同,类型就不相同,这点颠覆了我的编程认知,哈哈。

package main

func main() {
	q := [...]int{1, 2, 3}
	q = [...]int{1, 2, 3, 4}
	println(q)
}

  上述代码编译后会报错:

# array-len
.\main.go:5:6: cannot use [...]int{…} (value of type [4]int) as type [3]int in assignment
键值对语法

  在字面量定义的语法里,键值对语法很有意思。它适合这种一种场景,除特殊的几个索引外,其余索引全部为0值。如我要构造一个长度为8的数组,第4个元素(以0开始)为7,就可以这样写:

package main

import "fmt"

func main() {
	array := [8]rune{4: 7}
	fmt.Println(array)
}

  输出:

[0 0 0 0 7 0 0 0]
值类型

  GoLang中数组是值类型,怎么理解呢?就是说把一个数组赋值给变量是把值赋过去,这点和java不一样,所以这个时候修改数组各个索引的值不会影响原变量。以一个例子来说明:

package main

import "fmt"

func main() {

	a := [...]rune{1, 2, 3}
	b := a
	b[0] = 2
	fmt.Println(a, b)
}

  输出结果是:

[1 2 3] [2 2 3]
多维数组

  多维数组,外层到内层是从左到右的写法,比如 3 × 4 3\times 4 3×4的二维数组,外层是长度为3的数组,里面每个元素都是长度为4的数组,写起来就是[3][4].但是多维数组还有个奇怪的语法点,就是写字面量时,外层的最后一个逗号不能省略。我写段代码说明哪个逗号不能省略吧:

package main

import "fmt"

func main() {
	a := [3][4]rune{
		{1, 2, 3, 4},
		{2, 1, 3, 4},
		{3, 1, 2, 4},// 这个逗号不能省略
	}
	fmt.Println(a)
}

  输出结果:

[[1 2 3 4] [2 1 3 4] [3 1 2 4]]

  对于用三个点自动推断长度的语法,在多维数组这,只能用于第一维度。所以上面的例子可以改成:

	a := [...][4]rune{
		{1, 2, 3, 4},
		{2, 1, 3, 4},
		{3, 1, 2, 4}, // 这个逗号不能省略
	}

  如果强行用,编译不会报错,但是运行会报错:

.\main.go:6:12: invalid use of [...] array (outside a composite literal)