【GO学习笔记】数组

在这里插入图片描述


数组是同一种数据类型元素的集合。 在Go语言中,数组从声明时就确定,使用时可以修改数组成员,但是数组大小不可变化。

数组定义

var 数组变量名 [元素数量]T

数组的初始化

数组的初始化也有很多方式。

方法一

声明一个数组,并设置为零值

var array [5]int

每个元素都初始化为0,也就是整型的零值。

方法二

使用数组字面量声明数组

// 声明一个包含5 个元素的整型数组
// 用具体值初始化每个元素
array := [5]int{10, 20, 30, 40, 50}

方法三

让Go 自动计算声明数组的长度,如果使用...替代数组的长度。

// 声明一个整型数组
// 用具体值初始化每个元素
// 容量由初始化值的数量决定
array := [...]int{10, 20, 30, 40, 50}

方法四

声明数组并指定特定元素的值

// 声明一个有5 个元素的数组
// 用具体值初始化索引为1 和2 的元素
// 其余元素保持零值
array := [5]int{1: 10, 2: 20}

使用数组

访问数组元素

// 声明一个包含5 个元素的整型数组
// 用具体值初始为每个元素
array := [5]int{10, 20, 30, 40, 50}
// 修改索引为2 的元素的值
array[2] = 35

访问指针数组的元素

// 声明包含5 个元素的指向整数的数组
// 用整型指针初始化索引为0 和1 的数组元素
array := [5]*int{0: new(int), 1: new(int)}
// 为索引为0 和1 的元素赋值
*array[0] = 10
*array[1] = 20

[n]T表示指针数组,[n]T表示数组指针

把同样类型的一个数组赋值给另外一个数组

// 声明第一个包含5 个元素的字符串数组
var array1 [5]string
// 声明第二个包含5 个元素的字符串数组
// 用颜色初始化数组
array2 := [5]string{"Red", "Blue", "Green", "Yellow", "Pink"}
// 把array2 的值复制到array1
array1 = array2

数组变量的类型包括数组长度和每个元素的类型。只有这两部分都相同的数组,才是类型相同的数组,才能互相赋值。

编译器会阻止类型不同的数组互相赋值

// 声明第一个包含4 个元素的字符串数组
var array1 [4]string
// 声明第二个包含5 个元素的字符串数组
// 使用颜色初始化数组
array2 := [5]string{"Red", "Blue", "Green", "Yellow", "Pink"}
// 将array2 复制给array1
array1 = array2

输出:

Compiler Error:
cannot use array2 (type [5]string) as type [4]string in assignment

把一个指针数组赋值给另一个

// 声明第一个包含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

复制之后,两个数组指向同一组字符串

在函数间传递数组

根据内存和性能来看,在函数间传递数组是一个开销很大的操作。在函数之间传递变量时,总是以值的方式传递的。如果这个变量是一个数组,意味着整个数组,不管有多长,都会完整复制,并传递给函数。

使用值传递,在函数间传递大数组

// 声明一个需要8 MB 的数组
var array [1e6]int
// 将数组传递给函数foo
foo(array)

// 函数foo 接受一个100 万个整型值的数组
func foo(array [1e6]int) {
...
}

每次函数 foo 被调用时,必须在栈上分配8 MB 的内存。

使用指针在函数间传递大数组

var array [1e6]int
// 将数组的地址传递给函数foo
foo(&array)
// 函数foo 接受一个指向100 万个整型值的数组的指针
func foo(array *[1e6]int) {
...
}

这次函数 foo 接受一个指向100 万个整型值的数组的指针。现在将数组的地址传入函数,只需要在栈上分配8 字节的内存给指针就可以。这个操作会更有效地利用内存,性能也更好。不过要意识到,因为现在传递的是指针,
所以如果改变指针指向的值,会改变共享的内存。

数组是值类型

数组是值类型,赋值和传参会复制整个数组。因此改变副本的值,不会改变本身的值。

func modifyArray(x [3]int) {
	x[0] = 100
}

func modifyArray2(x [3][2]int) {
	x[2][0] = 100
}
func main() {
	a := [3]int{10, 20, 30}
	modifyArray(a) //在modify中修改的是a的副本x
	fmt.Println(a) //[10 20 30]
	b := [3][2]int{
		{1, 1},
		{1, 1},
		{1, 1},
	}
	modifyArray2(b) //在modify中修改的是b的副本x
	fmt.Println(b)  //[[1 1] [1 1] [1 1]]
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值