切片是对数组中连续片段的引用。 这个数组称为相关数组。 通常是匿名的。 (因此,切片是引用类型的。 )因此,与C/C的数组类型和Python的list类型相似。 此片段可以是整个数组,也可以是由开始索引和结束索引标识的某些项目的子集。 请注意,用于结束索引标记的项目不包括在切片中。

在Go语言中,Slice表示变长的数组,数组内的各要素具有相同的类型。 slice型一般写为[]T。 其中t表示slice中元素的类型。 slice的语法与数组相似,只是没有固定长度。

Go语言片的内部结构包括地址、大小和容量。 切片通常用于快速处理单个数据集。 如果把数据的集合比作年糕,那么切片就是你想要的“那块”。 的过程包括从哪里开始(这是切片的地址)和切多久(这是切片的大小)。 容量可以理解为如下图所示放切片的口袋的大小。

图:片结构和内存分配

从数组或切片生成新切片

默认情况下,片指向数组或片本身的连续内存区域。

从连续的内存区域生成片是常见的操作,格式为slice[开始位置:结束位置]

slice表示目标切片中的对象。

开始位置与目标切片中对象的索引相对应。

结束位置与目标切片的结束索引相对应。

从数组中生成切片。 代码如下所示。

vara=[3] int { 1,2,3 } fmt.println (a,a(1:2 ) ) )

a是具有三个整数元素的数组,初始化值1~3。 a[1:2]使您可以生成新切片。 代码的执行结果如下。 [123][2]

[2]是a[1:2]切片操作的结果。

从数组或切片生成新切片具有以下特性:

检索到的要素数为结束位置-开始位置。

检索元素不包含与结束位置对应的索引,切片中的最后一个元素是使用slice[Len]检索的。

对于缺省起始位置,表示从连续区域的开头到结束位置。

缺省结束位置表示从开始位置到整个连续区域的末尾。

缺省情况下,两者都与切片本身等效。

如果两者同时为0,则等效于空切片,通常用于切片重置。

如果根据索引位置取切片slice元素的值,则值的范围为(0到0~len(slice(-1 ) ),过冲将报告运行时错误。 生成切片时,可以用len(slice )填充结束位置,但不会报告错误。

通过以下具体例子熟悉切片的特性。

1 )从指定范围生成切片

切片和排列是不可分割的。 如果将排列理解为办公楼的话,切片会将不同的连续楼层租给用户。 租赁流程必须选择起始层和终止层,并且此流程将生成切片。 示例代码如下所示。

varhighrisebuilding [ 30 ] int fori :=0; i30; i {highRiseBuilding[i]=i 1}//区间fmt.println (highrise building [ 10336015 ] ) /从中间到尾部的所有元素fmt.println ) highrise be

代码输出如下所示。 [1112131415]

[21222324252627282930]

[12]在

代码中建造了30层的高层建筑。 数组的元素值为1到30,表示不同的独立层。 输出的结果是不同的租赁计划。

代码说明如下。

第8行,试着租区间层。

第11行,20层以上出租。

第14行,租赁2楼以下,一般为商用铺装。

切片就像c语言的指针。 指针可以运算,但代价是内存操作越界。 片根据指针增加大小,以限制与片对应的内存空间。 与指针相比,切片更安全、更强大,因为在使用切片时无法手动调整切片内部的地址和大小。

2 )表示原始切片

如果生成的切片格式同时忽略开始和结束范围,则生成的切片表示与原始切片一致的切片,并且生成的切片与原始切片的数据内容一致。 代码如下所示。

a :=[ ] int { 1,2,3 } fmt.println (a [ : ] ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )。

a是具有三个要素的切片。 用a[:]操作a切片时,得到的切片与a切片一致,代码输出如下。 [123]

3 )重置切片,清空现有元素

如果切片的开始位置和结束位置都设置为0,则生成的切片将为空,如以下代码所示:

a :=[ ] int { 1,2,3 } fmt.println (a [ 0:0 ] ) ) ) ) ) ) ) ) ) ) ) ) ) )。

代码输出如下所示。 []

直接声明新切片

除了从原始数组或切片生成切片外,还可以声明新切片。 每种类型都可以具有表示多个类型元素的连续集合的切片类型。 因此,也可以声明切片类型。 片的声明格式如下。 varname[]T

name表示切片类型的变量名称。

t表示与切片类型相对应的元素类型。

以下代码说明了如何使用切片声明。

//声明字符串片varstrList[]stri

ng//声明整型切片varnumList[]int//声明一个空切片varnumListEmpty=[]int{}//输出3个切片fmt.Println(strList,numList,numListEmpty)//输出3个切片大小fmt.Println(len(strList),len(numList),len(numListEmpty))//切片判定空的结果fmt.Println(strList==nil)fmt.Println(numList==nil)fmt.Println(numListEmpty==nil)

代码输出结果:[][][]

000

true

true

false

代码说明如下:

第2行,声明一个字符串切片,切片中拥有多个字符串。

第5行,声明一个整型切片,切片中拥有多个整型数值。

第8行,将numListEmpty声明为一个整型切片。本来会在{}中填充切片的初始化元素,这里没有填充,所以切片是空的。但此时numListEmpty已经被分配了内存,但没有元素。

第11行,切片均没有任何元素,3个切片输出元素内容均为空。

第14行,没有对切片进行任何操作,strList和numList没有指向任何数组或者其他切片。

第17行和第18行,声明但未使用的切片的默认值是nil。strList和numList也是nil,所以和nil比较的结果是true。

第19行,numListEmpty已经被分配到了内存,但没有元素,因此和nil比较时是false。

切片是动态结构,只能与nil判定相等,不能互相判等时。

声明新的切片后,可以使用 append() 函数来添加元素。

使用make()函数构造切片

如果需要动态地创建一个切片,可以使用make()内建函数,格式如下:make([]T,size,cap)

T:切片的元素类型。

size:就是为这个类型分配多少个元素。

cap:预分配的元素数量,这个值设定后不影响size,只是能提前分配空间,降低多次分配空间造成的性能问题。

示例如下:

a:=make([]int,2)b:=make([]int,2,10)fmt.Println(a,b)fmt.Println(len(a),len(b))

代码输出如下:[00][00]

22

a和b均是预分配2个元素的切片,只是b的内部存储空间已经分配了10个,但实际使用了2个元素。

容量不会影响当前的元素个数,因此a和b取len都是2。

温馨提示

使用make()函数生成的切片一定发生了内存分配操作。但给定开始与结束位置(包括切片复位)的切片只是将新的切片结构指向已经分配好的内存区域,设定开始与结束位置,不会发生内存分配操作。

切片不一定必须经过make()函数才能使用。生成切片、声明后使用append()函数均可以正常使用切片。