访问数组元素:
数组中的每个元素都可以通过“[]”和一个从0开始的索引进行访问
数组的长度可由内置函数len来确定。在声明数组时,未被赋值元素的值是对应类型的零值。下面看一个例子
package mainfunc main(){var planets [8]stringplanets[0] = "Mercury"planets[1] = "Venus"planets[2] = "Earth"earth := planets[2]fmt.Println(earth)fmt.Println(len(planets))fmt.Println(planets[3] = "")
}
结果自行编译运行查看哈。
数组越界:
Go编译器在检测到对越界元素的访问时会报错。如果Go编译器在编译时未能发现越界错误,那么程序在运行时会出现panic,而Panic会导致程序崩溃。
var planets [8]stringi := 8planets[i] = "Pluto"pluto := planets[i]fmt.Println(pluto) //以上程序报错,数组越界。[8]指数组的内存为8,从0开始数
使用复合字面值初始化数组:
复合字面值(composite literal)是一种给复合类型初始化的紧凑语法。Go的复合字面值允许我们只用一步就完成数组声明和数组初始化两步操作:
dwarfs := [5]string{"Ceres", "Pluto", "Haumea", "Makemake", "Eris"}
可以在复合字面值里使用“...”作为数组的长度,这样,Go编译器会自动计算出数组的元素数量
无论哪种方式,数组的长度都是固定的。
//复合字面值初始化数组planets1 := [...]string{"Mercury","Venus","Earth","Mars","Jupiter","Saturn","Pluto", //数组的最后一个参数后要补逗号
下面来看两个遍历数组的例子:
//遍历数组,法一:dwarfs := [5]string{"Ceres", "Pluto", "Haumea", "Makemake", "Eris"}for i := 0; i < len(dwarfs); i++ {dwarf := dwarfs[i] //此处的dwarf和下方的dwarf同时定义但不报错,是闭包现象:此处的dwarf被封闭在了for循环函数内。fmt.Println(i+1, dwarf) //人性化设计}//法二:for i, dwarf := range dwarfs {fmt.Println(i, dwarf)}
数组的复制:
无论数组赋值给新的变量还是将它传递给函数,都会产生一个完整的数组副本。
planets := [...]string{"Mercury","Venus","Earth","Mars","Jupiter","Saturn","Pluto", //数组的最后一个参数后要补逗号}planetsMarkII := planets //数组复制planets[2] = "whoops"fmt.Println(planets)fmt.Println(planetsMarkII)
数组也是一种值,函数通过值传递来接受参数。所以数组作为函数的参数就非常的低效。
func terraform(planets [7]string) {for i := range planets {planets[i] = "New" + planets[i]}
}func main(){planets := [...]string{"Mercury","Venus","Earth","Mars","Jupiter","Saturn","Pluto", //数组的最后一个参数后要补逗号}planets[6] = "rock"terraform(planets)fmt.Println(planets)
}
数组的长度也是数组类型的一部分(尝试将长度不符的数组作为参数传递,将会报错)
函数一般使用slice(切片)而不是数组作为参数,这个内容下一节会讲到。
再来看一个二维数组的例子
var board [8][8]stringboard[0][0] = "r"board[0][7] = "r"for column := range board[1] { //把二维数组board的第二行全部替换为Pboard[1][column] = "p"}fmt.Print(board)