Golang——数组与切片的区别

/ 0评 / 0

在Golang中顺序容器有两种,一种是普通的数组,一种是切片。


数组(array)

数组创建方式分为两种,一种是通过字面值,一种是通过new

image.png

结果

image.png

首先注意到,数组在创建的时候必须是在[ ]中指明了元素个数,或者使用[...]结合{1, 2, 3}来创建也是可以的,因为这样也算是定好了数组中元素个数。同时数组的类型是[N]Type,即大小+类型,也就是说对于一个数组,只有大小和元素类型都相同时才认为他们是同一个类型,才可以互相直接赋值,这样的用法是错误的,编译不过去

image.png

go中数组就像C/C++中的原生数组一样是静态的,go中数组的底层结构也就是原生的内存结构,即一段连续的内存,但是在go中关于数组有个非常不同于大部分其他语言的地方:数组在go中是是值类型

所谓值类型就是在参数传递时不会传值,形参会建立一份关于实参的深拷贝,同类型变量赋值是也会进行一份深拷贝,而不是简单的复制地址

当同类型变量间赋值时

image.png

结果

image.png

在传递参数时

image.png

结果

image.png

因此用数组传递数组时应该使用数组指针,如下

image.png

结果

image.png


切片(slice)

切片是引用类型,先明确它的底层结构 

image.png

可以看到切片底层是对数组的封装,因此也切片经常用于对数组某一段的截取

其中len指明可读可写的实际长度,cap指明整个切片可用的空间大小,实际长度len后的只能通过切片的专属函数append来在末尾追加,同时要注意接收append的返回值,因为append后完全有可能超过切片底层数组的cap,此时会分配新的底层数组给切片,因此每次append的返回的切片必须被接收,之后应该使用的是这个返回的切片而不是原切片。

对比着数组的创建,看看切片的创建,切片的创建分为两种,一种字面值,一种是使用make,注意不可以使用new

先看通过字面值

image.png

结果

image.png

通过make

image.png

结果

image.png

可以看到因为切片是引用类型,其赋值都是浅拷贝即对slice底层结构的简单赋值,因此在传参时相比起数组也能非常方便

image.png

结果

image.png


其实数组与切片的区别并不能列举出很多来,因为本身都不是什么复杂的结构,但是就是有人弄得不明不白,分不清这个地方创建的是数组还是切片,因此这些基础一定要踏实的弄明白。

简单总结一下数组与切片的区别:

1、数组是切片的底层,是静态的,切片通过封装数组来实现动态

2、数组是值类型,切片是引用类型

发表评论

电子邮件地址不会被公开。 必填项已用*标注