参考的文章
OverNote-Golang
Golang-100-Days-数组
1.1 什么是数组
Go语言提供了数组类型的数据结构,数组是具有相同类型的一组已编号且长度固定的数据项序列,这种类型可以是任意原始类型,例如整形/字符串/自定义类型
数组元素可以通过索引来读取(从0开始)
数组一旦定义后,大小不能更改。
1.2 声明和初始化数组
需要指明数组的大小和存储的数据类型
var balance [10]float32
var balance = [5]float32{10000.0,2.0,3.4,7.0,50.0}
初始化中的{}元素个数不能大于[]中的数字。如果忽略[]中的数字不设置数组大小,Go会根据元素的个数设置数组大小
var balance = []float32{1000.0, 2.0, 3.4, 7.0, 50.0}
数组的其他创建方式:
var a [4]float32 // 定义,但不初始化
var b = [5]string{"a", "b"} // 5个空间,后面不足的用默认值填充
var c = [5]int{'A', 'B', 'C', 'D', 'E'} // 存的是byte
d := [...] int{1, 2, 3, 4, 5} // 自动设置数组的大小,这其实变化成了切片
e := [5] int32{2: 10, 4: 11} // 根据索引有选择的初始化,没选择的使用默认值
fmt.Println(a, b, c, d, e)
/*
[0 0 0 0] [a b ] [65 66 67 68 69] [1 2 3 4 5] [0 0 10 0 11]
*/
数组访问跟其他语言一样直接变量名加索引即可
a := [5]int32{1, 3, 4, 5}
b := a[3] // 5
fmt.Println(a, b)
数组的长度,可以通过len()函数获取
a := [5]int32{1, 2, 3, 4}
b := len(a) // 5,因为长度已经初始化给出了
c := [...]int32{1, 2, 3, 4}
d := len(c) // 4
fmt.Println(b, d)
遍历数组,可以使用原始的方法进行遍历,通过len()确定遍历长度
a := [...]int32{1, 2, 3, 4, 5}
for i := 0; i < len(a); i++ {
fmt.Println(a[i])
}
第二种遍历方法就是通过range进行遍历
b := [...]int32{1, 2, 4, 5, 6}
for k, v := range b {
fmt.Printf("index: %v,value:%v\n", k, v)
}
// 如果不想要其中的key,可以使用缺省定义符号_
c := [...]int32{1, 2, 4, 5, 6}
for _, v := range c {
fmt.Printf("value:%v\n", v)
}
// 也可以直接获取索引,然后获取值
for i := range c {
fmt.Println("Array item", i, "is", c[i])
}
1.3 多维数组定义
//定义一个3行4列的二维数组,如果某位置没有赋值,就使用默认值
a := [3][4]int32{{1, 2, 3, 4}, {5, 6, 7}, {10, 11}} // 注意最外层的大括号
for i := 0; i < len(a); i++ {
fmt.Println(a[i])
}
/*
[1 2 3 4]
[5 6 7 0]
[10 11 0 0]
*/
1.4 数组是值类型
数组是值类型,Go中的数组是值类型,而不是引用类型,这意味着当它们被分配给一个新变量时,将把原始数组的副本分配给新变量。如果对新变量进行了更改,则不会在原始数组中反应。
a := [...]string{"USA", "China", "India", "Germany", "France"}
b := a // a copy of a is assigned to b
b[0] = "Singapore"
fmt.Println("a is ", a)
fmt.Println("b is ", b)
/*
a is [USA China India Germany France]
b is [Singapore China India Germany France]
*/
1.5 不同定义的区别
var arr1 = new([5]int)
var arr2 [5]int
上面两种定义方式,arr1的类型是*[5]int,而arr2得类型是[5]int。这样的结果就是把一个数组赋值给另一个时,需要在做一次数组内存的拷贝操作,例如:
arr2: = *arr1
arr2[2] = 100
这样两个数组就有了相同的值,在赋值后需改rr2不会对arr1生效,所以在函数中数组作为参数参入时,如func1(arr2),会产生一次数组拷贝,func1方法不会修改原始的数组arr2,如果想修改原数组,那么arr2必须通过&操作符以引用的方式传过来,例如func1(&arr2),示例:
func main() {
a := [5]int{1, 2, 3, 4, 5}
arrF3(a)
fmt.Println(a)
b := [5]int{1, 2, 3, 4, 5}
arrF4(&b)
fmt.Println(b)
}
func arrF3(arr [5]int) {
arr[1] = 200
}
func arrF4(arr *[5]int) {
(*arr)[1] = 200
}
/*
[1 2 3 4 5]
[1 200 3 4 5]
*/
2.1 多维数组
数组通常是以为的,但是可以用来组装成多维数组例如:[3][5]int,[2][2][2]float64等。
示例:
func main() {
var table [WIDTH][HEIGHT] int
for y := 0; y < WIDTH; y++ {
for x := 0; x < HEIGHT; x++ {
table[x][y] = (x + 1) * (y + 1)
}
}
// 遍历方式一
for i := 0; i < WIDTH; i++ {
for j := 0; j < HEIGHT; j++ {
fmt.Printf("%d%s", table[i][j], "\t")
}
fmt.Println("")
}
fmt.Println("***************************")
// 遍历方式二
for _, v := range table {
for _, v2 := range v {
fmt.Printf("%d%s", v2, "\t")
}
fmt.Println("")
}
}
/*
1 2 3 4
2 4 6 8
3 6 9 12
4 8 12 16
***************************
1 2 3 4
2 4 6 8
3 6 9 12
4 8 12 16
*/