通过切片创建新的切片
切片之所以被称为切片,是因为创建一个新的切片,也就是把底层数组切出一部分。通过切片创建新切片的语法如下:
slice[i:j]slice[i:j:k]
其中
i表示从slice的第几个元素开始切j表示切到第几个元素(不包括)。切片的长度为(j-i)k控制切片的容量(k-i),如果没有给定k,则表示切到底层数组的最尾部。
下面是几种常见的简写形式:
slice[i:] // 从 i 切到最尾部slice[:j] // 从最开头切到 j(不包含 j)slice[:] // 从头切到尾,等价于复制整个 slice
让我们通过下面的例子来理解通过切片创建新的切片的本质:
// 创建一个整型切片// 其长度和容量都是 5 个元素myNum := []int{10, 20, 30, 40, 50}// 创建一个新切片// 其长度为 2 个元素,容量为 4 个元素newNum := slice[1:3]
执行上面的代码后,我们有了两个切片,它们共享同一段底层数组,但通过不同的切片会看到底层数组的不同部分:

:::warning 注意,截取新切片时的原则是 “左含右不含”。
:::
所以 newNum 是从 myNum 的index=1处开始截取,截取到 index=3 的前一个元素,也就是不包含 index=3 这个元素。所以,新的 newNum 是由 myNum 中的第 2 个元素、第 3 个元素组成的新的切片构,长度为 2,容量为 4。
切片 myNum 能够看到底层数组全部 5 个元素的容量,而 newNum 能看到的底层数组的容量只有 4 个元素。newNum 无法访问到底层数组的第一个元素。所以,对 newNum 来说,那个元素就是不存在的。
共享底层数组的切片
需要注意的是:
:::danger
现在两个切片 myNum 和 newNum 共享同一个底层数组。如果一个切片修改了该底层数组的共享部分,另一个切片也能感知到 (请参考前图):
:::
// 修改 newNum 索引为 1 的元素// 同时也修改了原切片 myNum 的索引为 2 的元素newNum[1] = 35
把 35 赋值给 newNum 索引为 1 的元素的同时也是在修改 myNum 索引为 2 的元素:

切片只能访问到其长度内的元素
切片只能访问到其长度内的元素,试图访问超出其长度的元素将会导致语言运行时异常。在使用这部分元素前,必须将其合并到切片的长度里。下面的代码试图为 newNum 中的元素赋值:
// 修改 newNum 索引为 3 的元素// 这个元素对于 newNum 来说并不存在newNum[3] = 45
上面的代码可以通过编译,但是会产生运行时错误:
panic: runtime error: index out of range
