数组基本上在除了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)
数组是定长的,如果要可扩容的,就需要使用切片了。