8.5. 切片(基础的重中之重)
切片
切片(slice)概念
切片:切片与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大,所以可以将切片理解成“动态数组”,但是,它不是数组。
数组的缺点
在讲解切片(slice)之前,大家思考一下数组有什么问题?
第一:数组定义完,长度是固定的。
var num [ 5]int =[ 5]int{ l,2,3,4,5}
fmt . Println(num)
定义的num数组长度是5,表示只能存储5个整型数字,现在向数组num中追加一个数字,这时会出错
第二:使用数组作为函数参数进行传递时,如果实参为5个元素的整型数组,那么形参也必须5个元素的整型数组,否则出错。
使用切片来进行解决数组的缺点
针对以上两个问题,可以使用切片来进行解决。
切片:切片与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大,所以可以将切片理解成“动态数组”,但是,它不是数组。
切片与数组区别
通过定义,来比较一下切片与数组的区别
- 先回顾数组的基本定义初始化:
a:=[5]int{ }
数组中[ ]是一个固定的数字,表示长度。定义完后,长度是固定,最多存储5个数字。
- 切片的基本定义初始化如下:
看定义的方式,发现与数组很相似,但是注意:切片中的[ ]是空的,或者是“…”. 切片的长度和容量可以不固定。s:=[ ]int{ }//定义空切片
现在通过程序演示,动态向切片中追加数据
//初始化切片
s := []int{ 1,2,3 }
//通过append函数向切片中追加数据中
s = append(s, 5, 6,7)
fmt . Println(s)
append( )函数,第一个参数表示向哪个切片追加数据,后面表示具体追加的数据。
最终输出结果为:
[1 2 3 5 6 7]
切片定义方式
第一种,var
var s1 []int //
声明切片和声明数组一样,只是少了长度,此为空(nil)切片
第二种 通过make( )函数实现
借助make函数, 格式 make(切片类型, 长度, 容量)
s := make([]int, 5, 10)
什么是切片的长度与容量?
长度与容量 定义
长度是已经初始化的空间(以上切片s初始空间默认值都是0)。
容量是已经开辟的空间,包括已经初始化的空间和空闲的空间。
我们可以通过如下图来理解切片的长度与容量:
该切片的长度是5(存有数据,注意如果没有赋值,默认值都是0),容量是10,只不过有5个空闲区域。
即使没有给切片s赋值,初始化的空间(长度)默认存储的数据都是0 。
演示如下:
s=make([]int, 5,8)|fmt . Println (s)
输出的结果是:
[0 0 0 0 0]
注意:切片长度要小于容量
在使用make( )函数定义切片时,一定要注意,切片长度要小于容量,例如:
s := make([]int, 10, 5) // 是错误的
是错误的。
注意: make( )函数中的容量参数是可以省略掉的
make( )函数中的容量参数是可以省略掉的,如:
s := make([]int, 10) // 省略容量
这时长度与容量是相等的,都是10.
计算切片的长度与容量
GO
语言提供了相应的函数来计算切片的长度与容量
s = make([]int, 5,10)
fmt.Println("长度是:", len (s))
fmt.Println("容量是:", cap (s) )
给切片赋值
接下来给切片s赋值,可以通过下标的方式直接来进行赋值。如下所示:
// 通过指定下标方式完成赋值
s=make ( [ ]int, 5,10)
s[0]= l
s[l] = 2
也可以通过循环的方式来进行赋值。
s := make ([] int, 5, 10)
for i := 0; i < len (s); i++{
s[i] = i
}
在这里一定要注意,循环结束条件是小于切片的长度,而不是容量。因为,切片的长度是指的是初始化的空间。以下方式会出现异常错误。
for i := 0; i <cap (s) ; i++ {
s[i] = i
}
给切片赋完值后,怎样将切片中的数据打印出来呢?
第一种方式:直接通过下标的方式输出,例如:s[0],s[1]…..。
第二种方式:通过循环的方式,注意循环结束的条件,也是小于切片的长度,如下所示:
for i :=0; i <len (s) ; i++{
fmt .Println (s [i])
}
或者使用range方式输出:
for k, V := range s {
fmt . Println ( "下标:", k)fmt . Println ( "值:", v)
}
'
下一章,切片截取
请看下一章