数组与切片

1、数组
在Go语言里,数组是一个长度固定的数据类型,用于存储一段具有相同的类型的元素的连续块。数组存储的类型可以是内置类型,如整型或者字符串,也可以是某种结构类型。
1)数组的创建

//先声明,再赋值
	var array [5]int
	array[1] = 3
//创建固定长度的数组
array := [5]int{1,2,3,4,5}
//数组长度由初始化值的数量决定
array := [...]int{10,20,30,40,50}

其底层为:
在这里插入图片描述
2)在函数间传递数组
根据内存和性能来看,在函数间传递数组是一个开销很大的操作。在函数间传递变量时,总是以值的方式传递的。如果变量是一个数组,意味着整个数组,不管有多长,都会完整复制,并传递给函数。

	// 声明一个需要 8M 的数组
	var array [1e6]int
	//将数组传递给函数 foo
	foo(array)
	//函数foo接受一个100万个整型值的数组
	func foo (array [1e6]int){
		
	}

从上面的代码可知,每次函数 foo被调用时,必须在栈上分配8M的内存。之后,整个数组的值(8M的内存)被复制到刚分配的内存里。为了性能考虑,可以只传入数组的指针,这样只需要复制8字节的数据而不是8MB的内存数据到栈上。

	// 声明一个需要 8M 的数组
	var array [1e6]int
	//将数组传递给函数 foo
	foo(&array)
	//函数foo接受一个100万个整型值的数组
	func foo (array *[1e6]int){

	}

这样有效的利用了内存,也提升了性能。不过要注意,因为传递的是指针,则如果改变指针指向的值,会改变共享的内存。同时,利用切片也能更好的处理这些共享问题。
2、切片
切片是一种数据结构,这种数据结构便于使用和管理数据集合。切片是围绕动态数组的概念构建的,可以按需自动增长和缩小。切片的动态增长是通过内置函数append来实现的。还可以通过对切片再次切片来缩小切片的大小。因为切片的底层内存是在连续块中分配的,所以切片还能进行索引、迭代、垃圾回收。
1)切片的创建

	//切片的长度和容量都是5个元素
	slicie := make([]string,5)
	//切片的长度为3,容量为5
	slicie := make([]string,3,5)

注意数组和切片的声明的不同

	//创建有3个元素的整型数组
	array := [3]int{1,2,3}
	
	//创建长度和容量都是3的整型切片
	slice := []int{1,2,3}

使用切片创建切片

	//创建长度和容量都是5的整型切片
	slice := []int{10,20,30,40,50}
	
	//创建长度为2个元素,容量为4个元素的切片
	newSlice := slice[1:3]

其底层为:
在这里插入图片描述
对底层数组容量为k的切片 slice[i:j]来说,
长度: j - i
容量:k - i
2) 修改切片内容可能导致的结果

	slice := []int{10,20,30,40,50}
	newSlice := slice[1:3]
	newSlice[1] = 35

修改后,其为:
在这里插入图片描述
把35赋值给 newSlice的第二个元素(索引为1的元素)的同时也是在修改原来的slice的第3个元素。
3)使用 append向切片中增加元素时,
函数 append会智能地处理底层数组的容量增长。在切片的容量小于1000个元素时,总是成倍地增加容量,一旦元素个数超过1000,容量的增长因子会设为1.25,也就是会每次增加 25% 的容量。
在使用append函数操作时,其会首先使用可用的容量。一旦没有可用的容量,会分配一个新的底层数组,这导致其很容易忘记正在共享的底层数组。一旦发生这种情况,在切片的操作中很容易发生意想不到的问题。
如果在创建切片时,设置切片的容量和长度一样,就可以强制让切片的第一个append操作就创建新的底层数组,与原有的底层数组分离。新切片与原有的底层数组分离后,就可以安全地进行后续的操作了。
4) 切片的迭代

package main

import "fmt"

func main()  {
	slice := []int{10,20,30,40}

	for index,value := range slice{
		fmt.Printf("Value: %d Value-Addr: %X ElemAddr: %X\n",value,&value,&slice[index])
	}


}

其运行结果为:
在这里插入图片描述
原因:
在这里插入图片描述
range 创建了每个元素的副本,而不是直接返回对该元素的引用。在迭代过程中,其返回的变量是一个迭代过程中根据切片依次赋值的新变量,所以value的地址总是相同的,要想获取每个变量的地址,可以使用切片变量和索引值。
5)在函数间传递切片
在函数间传递切片就是以值的方式传递切片。在64位架构的机器上,一个切片需要24字节的内存:指针字段需要8字节,长度和容量分别需要8字节。由于和切片相关联的数据包含在底层数组里,不属于切片本身,所以讲切片复制到任意函数的时候,对底层数组大小都不会有影响。复制时只会复制切片本身,不会涉及底层数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值