8.5. 切片(基础的重中之重)

未匹配的标注
本文档最新版为 2023,旧版本可能放弃维护,推荐阅读最新版!

切片

切片(slice)概念

切片:切片与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大,所以可以将切片理解成“动态数组”,但是,它不是数组。

数组的缺点

在讲解切片(slice)之前,大家思考一下数组有什么问题?

第一:数组定义完,长度是固定的。

var num [ 5]int =[ 5]int{ l,2,3,4,5}
fmt . Println(num)

定义的num数组长度是5,表示只能存储5个整型数字,现在向数组num中追加一个数字,这时会出错

第二:使用数组作为函数参数进行传递时,如果实参为5个元素的整型数组,那么形参也必须5个元素的整型数组,否则出错。

使用切片来进行解决数组的缺点

针对以上两个问题,可以使用切片来进行解决。

切片:切片与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大,所以可以将切片理解成“动态数组”,但是,它不是数组。

切片与数组区别

通过定义,来比较一下切片与数组的区别

  1. 先回顾数组的基本定义初始化:
a:=[5]int{ }

数组中[ ]是一个固定的数字,表示长度。定义完后,长度是固定,最多存储5个数字。

  1. 切片的基本定义初始化如下:
    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)
}
'

下一章,切片截取

请看下一章

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~