Go语言——数组array
[TOC]
小结:
- 数组⻓度必须是常量,且是类型的组成部分。 [2]int 和 [3]int 是不同类型。
- ⽀持 “==”、 “!=” 操作符,因为内存总是被初始化过的。
- 指针数组 [n]T,数组指针 [n]T。
- 可以使用new来创建数组,此方法返回一个指向数组的指针
- 数组是值类型,赋值和传参会复制整个数组,而不是指针。(指针数组也是值传递,将指针拷贝)
- 值拷贝⾏为会造成性能问题,通常会建议使⽤ slice,或数组指针。
1、什么是数组?
在go语言中,数组是一个长度固定的数据类型,用于存储一段具有相同类型元素的连续块。存储的类型可以是内置类型,如整型、字符串也可以是某种结构类型。
2、数组的特点
数组占用的内存是连续的,所以cpu能把正在使用的数据缓存更久,并且连续的内存很容易计算索引,数组每个元素类型又相同,所以使用数组,计算速度会非常快。
注意:数组一旦声明,存储的数据类型和数组长度就不能改变,如果需要存储更多的元素,就得重新开辟内存空间,然后把原数组拷贝过去。
3、声明和初始化数组
(1)声明一个数组,并设置为零值
当数组初始化时,数组内每个元素都初始化为对应类型的零值
// 声明一个包含 5 个元素的整型数组
var array [5]int
(2)使用数组字面量声明数组
// 声明一个包含 5 个元素的整型数组
// 用具体值初始化每个元素
array := [5]int{10, 20, 30, 40, 50}
var array [5]int = [5]int{10, 20, 30, 40, 50}//当然这样也行
(3)使用… 让 Go 自动计算声明数组的长度
// 声明一个整型数组
// 用具体值初始化每个元素// 容量由初始化值的数量决定
array := [...]int{10, 20, 30, 40, 50}
(5)声明数组并指定特定元素的值
// 声明一个有 5 个元素的数组
// 用具体值初始化索引为 1 和 2 的元素
// 其余元素保持零值
array := [5]int{1: 10, 2: 20}
4、数组赋值
(1)把相同类型的数组赋值给另一个数组
// 声明第一个包含 5 个元素的字符串数组
var array1 [5]string
// 声明第二个包含 5 个元素的字符串数组
// 用颜色初始化数组
array2 := [5]string{"Red", "Blue", "Green", "Yellow", "Pink"}
// 把 array2 的值复制到 array1
array1 = array2
注意:数组变量的类型包括数组长度和每个元素的类型。只有这两部分都相同的数组,才是类型相同的数组,才能互相赋值 即 [3]string 和 [4]string 是不同类型的
(2)数组是值类型,赋值和传参会复制整个数组,而不是指针,比如指针数组,也是值的拷贝,只不过是复制的指针的值,而不会复制指针所指向的值
// 声明第一个包含 3 个元素的指向字符串的指针数组
var array1 [3]*string
// 声明第二个包含 3 个元素的指向字符串的指针数组
// 使用字符串指针初始化这个数组
array2 := [3]*string{new(string), new(string), new(string)}
// 使用颜色为每个元素赋值
*array2[0] = "Red"
*array2[1] = "Blue"
*array2[2] = "Green"
// 将 array2 复制给 array1
array1 = array2
//最终,他们还是指向了同一片内存地址,只是指针的值相同。
(3)注意区分指针数组和指向数组的指针。
//(1)指向数组的指针:
a:=[100]int{99:1}
var p *[100]int=&a
//上面两行代码表示,声明了一个长度100的数组,然后取出数组的地址赋给指针p,这里的p是一个指针,指向长度为100的数组的指针
// (2) 指针数组:
x, y := 1, 2
a := [...]*int{&x, &y}
//现在的代码表示: 声明两个变量x,y,然后分别取出他们的地址作为指针,这里的a是一个指针数组,存放的是x,y的存储地址,
5、二维数组
(1)声明二维数组
// 声明一个二维整型数组,两个维度分别存储 4 个元素和 2 个元素
var array [4][2]int
// 使用数组字面量来声明并初始化一个二维整型数组
array := [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}}
// 声明并初始化外层数组中索引为 1 个和 3 的元素
array := [4][2]int{1: {20, 21}, 3: {40, 41}}
// 声明并初始化外层数组和内层数组的单个元素
array := [4][2]int{1: {0: 20}, 3: {1: 41}}
//注意
b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能⽤ "..."。
(2)多维数组的类型包括每一维度的长度以及最终存储在元素中的数据的类型。
// 声明两个不同的二维整型数组
var array1 [2][2]int
var array2 [2][2]int
// 为每个元素赋值
array2[0][0] = 10
array2[0][1] = 20
array2[1][0] = 30
array2[1][1] = 40
// 将 array2 的值复制给 array1
array1 = array2
6、使用数组
(1)数组直接通过索引来使用。如array[2]=14 等等
// 声明一个包含 5 个元素的整型数组
// 用具体值初始为每个元素
array := [5]int{10, 20, 30, 40, 50}
// 修改索引为 2 的元素的值
array[2] = 35
(2)使用内置函数 len() 和cap()
使用内置函数len()和cap()返回数组长度和数组容量
package main
import "fmt"
func main() {
array := [2]int{}
fmt.Printf("数组长度:%d,数组容量:%d\n", len(array), cap(array))
}
//输出结果:数组长度:2,数组容量:2
(3)使用内置函数len()和cap()返回多维数组长度和多维数组容量
package main
import "fmt"
func main() {
array := [3][6]int{}
fmt.Printf("数组长度:%d,数组容量:%d\n", len(array), cap(array))
}
//数组长度:3,数组容量:3
7、数组的传递
当传递数组时,如果数组较大,那么值拷贝行为会造成性能问题,通常会建议使⽤ slice,或数组指针。