从零学 Go:切片的使用

·  阅读 526

这是我参与更文挑战的第9天,活动详情查看: 更文挑战

前文回顾

前面的文章主要介绍了 Go 基于语法中 Go 容器:数组。本文将会具体切片的使用。

Go 中常用的容器

Golang 中以标准库的方式提供了常用的容器实现,基本能够满足我们日常开发的需要。我们来具体学习下 Go 数组的使用。

切片

切片是对数组一个连续片段的引用,它是一个容量可变的序列。我们可以简单将切片理解为动态数组,它的内部结构包括底层数组指针、大小和容量,它通过指针引用底层数组,把对数据的读写操作限定在指定的区域内。

切片的结构体由三部分组成:

  • array 是指向底层存储数据数组的指针;
  • len 指当前切片的长度,即成员数量;
  • cap 指当前切片的容量,它总是大于等于 len

我们可以从原有数组中生成一个切片,那么生成的切片指针即指向原数组,生成的样式如下:

slice := source[begin:end]
复制代码

source表示生成切皮的原有数组,begin 表示切片的开始位置,end 表示切片的结束位置,不包含 end 索引指向的成员。具体效果如下例子所示:

source := [...]int{1,2,3}
sli := source[0:1]

fmt.Printf("sli value is %v\n", sli)
fmt.Printf("sli len is %v\n", len(sli))
fmt.Printf("sli cap is %v\n", cap(sli))
复制代码

输出的结果为:

sli value is [1]
sli len is 1
sli cap is 3
复制代码

在这个切片内,我们仅能访问长度内的值,如果访问的下标超过了切片的长度,编译器将会抛出下标越界的异常。如果此时我们对切片内的成员进行修改,因为切片作为指向原有数组的引用,对切片进行修改就是对原有数组进行修改,如下例子所示:

sli[0] = 4
fmt.Printf("sli value is %v\n", sli)
fmt.Printf("source value is %v\n", source)
复制代码

结果如下所示:

sli value is [4]
source value is [4 2 3]
复制代码

上面例子中我们修改了切片中的值,直接导致原数组中的值也发生了变化。

我们也可以通过 make 函数动态创建切片,在创建过程中指定切片的长度和容量,样式如下所示:

make([]T, size, cap)
复制代码

T 即切片中的成员类型,size 为当前切片具备的长度,cap 为当前切片预分配的长度,即切片的容量。例子如下所示:

sli = make([]int, 2, 4)
fmt.Printf("sli value is %v\n", sli)
fmt.Printf("sli len is %v\n", len(sli))
fmt.Printf("sli cap is %v\n", cap(sli))
复制代码

输出的结果如下:

sli value is [0 0]
sli len is 2
sli cap is 4
复制代码

从上述输出可以看到 make 函数创建的新切片中的成员都被初始化为类型的初始值。

小结

本文主要介绍了切片的基本使用,切片本质就是一个结构体,他里面包含三部分:address + len + cap,因此作为一个引用空间,该空间和元素空间完全是两个空间,所以切片的首地址和头号元素的首地址完全不同。

下面一篇文章将会对切面进行具体应用,并比较切片与数组的异同。

分类:
后端
标签: