切片是对数组中连续片段的引用。 这个数组称为相关数组。 通常是匿名的。 (因此,切片是引用类型的。 )因此,与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()函数均可以正常使用切片。