参考的文章
OverNote-Golang
Golang-100-Days-数组
1.1 什么是数组
Go语言提供了数组类型的数据结构,数组是具有相同类型的一组已编号且长度固定的数据项序列,这种类型可以是任意原始类型,例如整形/字符串/自定义类型
数组元素可以通过索引来读取(从0开始)
数组一旦定义后,大小不能更改。
1.2 声明和初始化数组
需要指明数组的大小和存储的数据类型
var balance [10]float32var 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'} // 存的是byted := [...] 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] // 5fmt.Println(a, b)
数组的长度,可以通过len()函数获取
a := [5]int32{1, 2, 3, 4}b := len(a) // 5,因为长度已经初始化给出了c := [...]int32{1, 2, 3, 4}d := len(c) // 4fmt.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 bb[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: = *arr1arr2[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] intfor 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 42 4 6 83 6 9 124 8 12 16***************************1 2 3 42 4 6 83 6 9 124 8 12 16*/
