Golang 切片综合指南( 二 )


声明数组与切片的区别

  • 如果你使用 [ ] 操作符中指定一个值 , 那么你在创建一个数组 。
  • 如果你不在 [ ] 中指定值 , 则创建一个切片 。
// 创建一个包含 3 个整数的数组 。 array := [3]int{10, 20, 30} // 创建一个长度和容量均为 3 的整型切片 。 slice := []int{10, 20, 30}声明一个 nil 切片nil// 创建一个整型 nil 切片 。 var slice []int32fmt.Println(slice == nil) // 此行将打印 truefmt.Println(len(slice))// 此行将打印 0fmt.Println(cap(slice))// 此行将打印 0
Golang 切片综合指南文章插图
声明一个空切片还可以通过初始化声明切片创建一个空切片 。
// 使用 make 来创建一个整型空切片 。 sliceOne := make([]int, 0)// 使用切片字面量创建一个整型空切片 。 sliceTwo := []int{}fmt.Println(sliceOne == nil) // 这将打印 falsefmt.Println(len(sliceOne))// 这将打印 0 fmt.Println(cap(sliceOne))// 这将打印 0fmt.Println(sliceTwo == nil) // 这将打印 falsefmt.Println(len(sliceTwo))// 这将打印 0fmt.Println(cap(sliceTwo))// 这将打印 0
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


推荐阅读