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 网站上。

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


暂无话题~