你可能很好奇,为啥 学习golang(3) 初探 过了 ,直接就来到了 学习golang(5) 初探,因为运维小学生不想提“4”字眼,以免犯忌讳,导致服务器无辜宕机。
数组
数组基本使用
数组作为go
基本的类型之一,我们来看下,和其他语言数组一样,需要先固定数组长度,且申请,然后再使用,我们来看下具体的用法。
数组申请
例如,我们可以看如下申请数组的例子
其中1,2 比较常见,不过多追诉,我们看看第三种,
申请语句 c := [...]int{1, 2, 3, 4, 5}
当数组长度定义为...
,那么该数组的长度是由数据元素决定的
注意,数组长度应当是常量,数组c
应当在编译时,就确定下来了的,本质上,该值还是常量。
我们尝试下运行
数组类型查看,并进行比较
我们可以使用 reflect.TypeOf
是可以看到变量的类型的
go
对于数组类型来看,[3]int
和[2]int
是同的数据类型,所以在编译的时候,会抛错,无法进行比较
我们尝试下,我们修改脚本
我们尝试运行下
这里可以看到,go
数组a
、b
、c
类型是[5]int
所以才能比较,我们再申请一个长度不一样的呢
我们尝试下运行
我们发现,报错了,原因是类型不一致
函数调用
和其他语言一样,数组函数调用,若不传入地址,则传入的是形参,形参修改不会影响到元数据
若想修改元数据,则需要传入指针
若我们传入形参,并且函数中进行修改
我们运行查看下数据是否改变
上述例子中,就是我们传入的是形参,相当于是数据的拷贝,当函数执行完毕后,函数中的数组a
则被销毁了,元数据没有影响的
如何修改元数据呢?
我们有2种方法
return
函数数组a
- 使用指针将
a
传入函数中
方法1: 将函数数组return
出来
我们再改变后,我们将数组的信息给返回给主函数,主函数适应数组接收
我们运行看看
方法2:我们传入指针
执行
slice
什么是slice
数组在go
中是使用的比较少的,使用最多的还是slice
,但是看slice
还是需要数组的相关知识才行。
你可以将slice
是一个可变长的“数组”,且它有三个属性构成: 起始地址、长度 和 容量。
我们使用make
可以声明slice
例如,我们有如下语句: a := make([]int,0,10)
则为分配一个底层数组为10,有效长度为0,且容量为10的切片,映射为数据结构,大概是这样的
其中,array
指向底层数组的起始地址、len
为有效长度,这里为0,cap
为容量,这里为10
当我们直接操作该slice
的时候,会出错,例如
我们尝试下
可以看到,报错为越界了
我们使用append
新增一个数据
语句 a = append(a,9)
此时,映射为数据结构,大概是这样的
我们此时再访问,a[0]
则是没有问题的,我们尝试下
执行
若当len
和cap
相等后,此时若又要append
数据,此时会开辟新空间
例如:
假设当前slice
数据结构如下
若此时,还需要append
追加元素,则
会申请一个新的数组,且将老数组数据拷贝到新数组中
又将cap
修改为最新大小,且将起始地址,指向新数组,并且将老数组销毁
然后执行追加即可,这基本上就是slice
变化过程(简化过的)
slice的基本使用
如何查看起始地址、长度和容量
如我们前面所述,每一个slice
有起始地址、长度和容量,那么我们如何查看其值呢?
我们可以使用cap()
来查询容量,使用len()
来查询长度,使用%p
查看地址
我们创建一个slice
容量为3,长度为2,且一直append
追加5个元素,我们看下
程序如下
我们执行一下
我们可以发现,当容量为 3 、6、12时候,我们起始地址都是新的,这也验证了我们之前所述的扩容逻辑
slice和数组搭配使用
slice
不仅可以创建底层数组,而且还可以直接对数组进行切片,例如
对于slice
b 而言,b[0]
== a[1]
,且b[0]
就是a[1]
的引用,即: 修改了b[0]
的值,就等同于修改了a[1]
的值
如上面所述,我们slice
不是有3个属性么,即: 起始地址、长度 以及 容量,那么对于slice b
它的数据结构大致为
我们尝试下
代码如下
我们执行查看下结果
可见,和我们猜想的无意,接下来的append
追加和上述又一致了,且len
== cap
后再进行追加,又会新开辟数组了。
我们来模拟尝试下
我们创建数组a[2],且创建slice
b = a[0:2]
,然后追加3个数据,再次修改b[0]
的元素,我们查看下a[0]
是否更改
我们代码编写如下
我们执行下看结果
可见,如果slice
引用了新的底层数组,老数组的信息是不会变动了的。
总结
其实在go
中slice
使用的比数组要广,slice
它有三个属性,分别是 起始地址,长度以及容量,当容量不够了的时候,go
会进行扩容,扩容的基本思想就是创建一个新的数组,然后将老数组的数据拷贝至新数组中,然后销毁老数组,且容量为新数组的长度,然后再进行扩容即可。
这就是数组 和 slice
的基本使用咯。