数组与切片
本章内容主要是探讨Go语言中数组和切片的概念及一些基本用法
前言
Go语言明显受到python语言的影响,在数组的基础上有了切片的概念,接下来让我们研究一下Go语言中切片的用法
一、切片是什么?
切片(slice)是对数组一个连续片段的引用(该数组我们称之为相关数组,通常是匿名的),所以切片是一个引用类型。这个片段可以是整个数组,或者是由起始和终止索引标识的一些项的子集
二、切片的基本操作
1.长度和容量
切片提供了一个相关数组的动态窗口
切片的长度即这个动态窗口的大小,通过len函数获取切片长度
切片的容量即与该切片相关的数组的大小,通过cap函数获取切片容量
代码如下(示例):
package main
import "fmt"
/*
切片提供了一个相关数组的动态窗口,数组是切片的构建块
切片是引用的,无需使用额外的内存并且比使用数组更加有效率
*/
func main() {
var arr1 [6]int
var slice []int = arr1[2:5] // item at index 5 not included
for i := 0; i < len(arr1); i++ {
arr1[i] = i
}
for i := 0; i < len(slice); i++ {
fmt.Printf("Slice at %d is %d\n", i, slice[i])
}
fmt.Printf("The length of arr1 is %d\n", len(arr1))
fmt.Printf("The length of slice is %d\n", len(slice))
fmt.Printf("The capacity of slice is %d\n", cap(slice))
fmt.Printf("grow the slice\n")
// grow the slice
slice = slice[0:4]
for i := 0; i < len(slice); i++ {
fmt.Printf("Slice at %d is %d\n", i, slice[i])
}
fmt.Printf("The length of slice is %d\n", len(slice))
fmt.Printf("The capacity of slice is %d\n", cap(slice))
}
2.使用make创建切片
因为切片是在数组的基础上提供一个动态窗口的功能,所以在创建切片的时候必须先有相对应的数组。如果相关的数组没有准备好,可以直接使用make函数创建切片,同时创建好相关数组
代码如下(示例):
package main
import "fmt"
/*
如果相关的数组并没有准备好,
可以通过make来直接创建切片,同时创建好相关数组
*/
func main() {
var slice = make([]int, 10)
for i := 0; i < len(slice); i++ {
slice[i] = 5 * i
}
for i := 0; i < len(slice); i++ {
fmt.Printf("Slice at %d is %d\n", i, slice[i])
}
fmt.Printf("The length of slice is %d\n", len(slice))
fmt.Printf("The length of slice is %d\n", cap(slice))
}
3.for-range用法
需要对切片进行遍历,除了常规的for循环方法,还可以使用for-range的简便用法(可以使用"_"的方法来忽略索引)
代码如下(示例):
package main
import "fmt"
/*
for range的用法
*/
func main() {
var slice = make([]int, 4)
slice[0] = 1
slice[1] = 2
slice[2] = 3
slice[3] = 4
for ix, value := range slice {
fmt.Printf("Slice at %d is %d\n", ix, value)
}
}
使用_来忽略索引
package main
import "fmt"
func main() {
var seasons = []string{"Spring", "Summer", "Autumn", "Winter"}
for ix, season := range seasons {
fmt.Printf("Seasons %d is %s\n", ix, season)
}
// _用于忽略索引
for _, season := range seasons {
fmt.Printf("%s\n", season)
}
}
4.切片重组
模拟切片长度的增长
package main
import "fmt"
func main() {
slice := make([]int, 0, 10)
fmt.Printf("The length of slice is %d\n", len(slice))
fmt.Printf("The cap of slice is %d\n", cap(slice))
// grow the slice
for i := 0; i < cap(slice); i++ {
slice = slice[0 : i+1]
slice[i] = i
fmt.Printf("The length of slice is %d\n", len(slice))
}
fmt.Println("print the slice")
for ix, value := range slice {
fmt.Printf("Slice at %d is %d\n", ix, value)
}
}
5.切片的复制和追加
使用copy函数,对切片进行复制
使用appned函数,对切片进行追加
package main
import "fmt"
func main() {
slFrom := []int{1, 2, 3}
slTo := make([]int, 10)
// copy返回复制元素的个数
n := copy(slTo, slFrom)
fmt.Println(slTo)
fmt.Printf("Copied %d elements\n", n)
// append
sl3 := []int{1, 2, 3}
sl3 = append(sl3, 4, 5, 6)
fmt.Println(sl3)
}
总结
要想理解切片必须先理解数组,数组有特定的用处,但是却有一些呆板,所以在Go语言的代码里并不是很常见。相对的,切片确实随处可见,它们构建在数组之上并且提供更强大的能力和便捷