Golang 切片综合指南( 二 )


Golang 切片综合指南文章插图
为任何特定索引赋值【Golang 切片综合指南】要修改单个元素的值 , 请使用 [ ] 操作符 。
// 创建一个整型切片 。 // 包含 4 个元素的长度和容量 。 slice := []int{10, 20, 30, 40}fmt.Println(slice) // 这将打印 [10 20 30 40]slice[1] = 25 // 改变索引 1 的值 。 fmt.Println(slice) // 这将打印 [10 25 30 40]
Golang 切片综合指南文章插图
对切片进行切片我们之所以称呼切片为切片 , 是因为你可以通过对底层数组的一部分进行切片来创建一个新的切片 。
/* 创建一个整型切片 。 长度和容量均为 5 。 */slice := []int{10, 20, 30, 40, 50}fmt.Println(slice)// 打印 [10 20 30 40 50]fmt.Println(len(slice)) // 打印 5fmt.Println(cap(slice)) // 打印 5/* 创建一个新切片 。 长度为 2 , 容量为 4 。 */newSlice := slice[1:3]fmt.Println(slice)// 打印 [10 20 30 40 50]fmt.Println(len(newSlice))// 打印 2fmt.Println(cap(newSlice))// 打印 4
Golang 切片综合指南文章插图
在执行切片操作之后 , 我们拥有两个共享同一底层数组的切片 。 然而 , 这两个切片以不同的方式查看底层数组 。 原始切片认为底层数组的容量为 5 , 但 newSlice 与之不同 , 对 newSlice 而言 , 底层数组的容量为 4 。 newSlice 无法访问位于其指针之前的底层数组元素 。 就 newSlice 而言 , 这些元素甚至并不存在 。 使用下面的方式可以为任意切片后的 newSlice 计算长度和容量 。
切片的长度与容量如何计算?切片 slice[i:j] 的 底层数组容量为 k 长度(Length):j - i 容量(Capacity):k - i
计算新的长度和容量切片 slice[1:3] 的 底层数组容量为 5 长度(Length):3 - 1 = 2 容量(Capacity):5 - 1 = 4
对一个切片进行更改的结果一个切片对底层数组的共享部分所做的更改可以被另一个切片看到 。
// 创建一个整型切片 。 // 长度和容量均为 5 。 slice := []int{10, 20, 30, 40, 50}// 创建一个新的切片 。 // 长度为 2 , 容量为 4 。 newSlice := slice[1:3]// 变更新切片索引 1 位置的元素 。 // 改变了原切片索引 2 位置的元素 。 newSlice[1] = 35将数值 35 分配给 newSlice 的第二个元素后 , 该更改也可以在原始切片的元素中被看到 。
运行时错误显示索引超出范围一个切片只能访问它长度以内的索引位 。 尝试访问超出长度的索引位元素将引发一个运行时错误 。 与切片容量相关联的元素只能用于切片增长 。
// 创建一个整型切片 。 // 长度和容量均为 5 。 slice := []int{10, 20, 30, 40, 50}// 创建一个新的切片 。 // 长度为 2 , 容量为 4 。 newSlice := slice[1:3]// 变更 newSlice 索引 3 位置的元素 。 // 对于 newSlice 而言 , 该元素不存在 。 newSlice[3] = 45/*Runtime Exception:panic: runtime error: index out of range*/切片增长与使用数组相比 , 使用切片的优势之一是:你可以根据需要增加切片的容量 。 当你使用内置函数 「append」 时 , Golang 会负责处理所有操作细节 。

  • 使用 append 前 , 你需要一个源 切片 和一个要追加的值 。
  • 当你的 append 调用并返回时 , 它将为你提供一个更改后的新切片 。
  • append 函数总会增加新切片的长度 。
  • 另一方面 , 容量可能会受到影响 , 也可能不会受到影响 , 这取决于源切片的可用容量 。
使用 append 向切片追加元素/* 创建一个整型切片 。长度和容量均为 5 。*/slice := []int{10, 20, 30, 40, 50}/* 创建一个新切片 。长度为 2 , 容量为 4 。 */newSlice := slice[1:3]fmt.Println(len(newSlice)) // 打印 2fmt.Println(cap(newSlice)) // 打印 4/* 向容量空间分配新元素 。将值 60 分配给新元素 。*/newSlice = append(newSlice, 60)fmt.Println(len(newSlice)) // 打印 3fmt.Println(cap(newSlice)) // 打印 4当切片的底层数组没有可用容量时 , append 函数将创建一个新的底层数组 , 拷贝正在引用的现有值 , 然后再分配新值 。
使用 append 增加切片的长度和容量// 创建一个整型切片 。 // 长度和容量均为 4 。 slice := []int{10, 20, 30, 40}fmt.Println(len(slice)) // 打印 4fmt.Println(cap(slice)) // 打印 4// 向切片追加新元素 。 // 将值 50 分配给新元素 。 newSlice= append(slice, 50)fmt.Println(len(newSlice)) // 打印 5fmt.Println(cap(newSlice)) // 打印 8
Golang 切片综合指南文章插图
在 append 操作后 , newSlice 被给予一个自有的底层数组 , 该底层数组的容量是原底层数组容量的两倍 。 在增加底层数组容量时 , append 操作十分聪明 。 举个例子 , 当切片的容量低于 1,000 个元素时 , 容量增长总是翻倍的 。 一旦元素的数量超过 1,000 个 , 容量就会增长 1.25 倍 , 即 25% 。 随着时间的推移 , 这种增长算法可能会在 Golang 中发生变化 。