【golang学习之旅】利用VScode安装设置Go开辟情况
【golang学习之旅】报错:a declared but not used
【golang学习之旅】Go 的基本数据类型
【golang学习之旅】深入理解字符串string数据类型
【golang学习之旅】go mod tidy
【golang学习之旅】记载一次 panic case : reflect: reflect.Value.SetInt using unaddressable value
【golang学习之旅】记载一次 error case : full error output: cc1: error: unrecognized command line option
【golang学习之旅】Go程序快速开始 & Go程序开辟的基本留意事项
【golang学习之旅】Go语言常用转义字符
【golang学习之旅】Go中的变量(1)
【golang学习之旅】Go中的变量——基本数据类型(1)
【golang学习之旅】Go中的变量——基本数据类型(2)
【golang学习之旅】复杂数据类型——指针 & 函数
【golang学习之旅】耽误调用——defer
1. 概念
有其他编程语言基础的同学应该对数组不生疏。数组是一种固定长度、同类型元素的有序集合。
留意事项:如果我们想让数组元素类型为恣意类型的话可以利用空接口(后面的文章会提到)作为类型
与许多其他编程语言中的数组类似,Go语言中的数组也通过索引来访问其元素,索引从0开始,直到数组长度减1。(数组以 0 开始在所有类 C 语言中是相似的)。数组的类型由其元素类型和长度共同决定,因此[5]int和[10]int被视为两种完全不同的类型。因此在 Go 语言中很少直接利用数组(不同长度的数组因为类型不同无法直接赋值)。和数组对应的类型是切片,切片是可以动态增长和收缩的序列,切片的功能也更加灵活,但是要理解切片的工作原理照旧要先理解数组。
下面介绍在Go语言中数组是如何声明和利用的。 2. 数组的声明与初始化
这里要区分一下Go语言中的数组和C语言中的数组的区别。
Go 语言中数组是值类型。一个数组变量即体现整个数组,它并不是隐式的指向第一个元素的指针(比如 C 语言的数组),而是一个完备的值。这意味着当你将数组赋值给另一个变量或将其作为函数参数通报时,现实上是在复制整个数组。这大概导致在处置惩罚大型数组时性能下降。为了避免复制数组带来的开销,可以通报一个指向数组的指针,但是数组指针并不是数组。
比如:
var a = [...]int{1, 2, 3} // a 是一个数组
var b = &a // b 是指向数组的指针
fmt.Println(a[0], a[1]) // 打印数组的前 2 个元素
fmt.Println(b[0], b[1]) // 通过数组指针访问数组元素的方式和数组类似
for i, v := range b { // 通过数组指针迭代数组的元素
fmt.Println(i, v)
}
复制代码
其中 b 是指向 a 数组的指针,但是通过 b 访问数组中元素的写法和 a 类似的。其实数组指针类型除了类型和数组不同之外,通过数组指针操作数组的方式和通过数组自己的操作类似,而且数组指针赋值时只会拷贝一个指针。但是数组指针类型依然不够灵活,因为数组的长度是数组类型的组成部分,指向不同长度数组的数组指针类型也是完全不同的。
3.2 遍历数组
我们可以用 for 循环来迭代数组。下面常见的几种方式都可以用来遍历数组:
for i := range a {
fmt.Printf("a[%d]: %d\n", i, a[i])
}
for i, v := range b {
fmt.Printf("b[%d]: %d\n", i, v)
}
for i := 0; i < len(c); i++ {
fmt.Printf("c[%d]: %d\n", i, c[i])
}
复制代码
用 for range 方式迭代的性能大概会更好一些,因为这种迭代可以包管不会出现数组越界的情形,每轮迭代对数组元素的访问时可以省去对下标越界的判断。