主要讲解Go语言中数组、切片(Slice) 的使用
主要知识点:
- 熟悉定义数组的几种方式
- 二维数组的用法
- 数组是值类型(默认情况下 Go中所有的参数传递都是值传递)
- [3]int 、[5]int 长度不一样,被认为是不同的数据类型
- Go语言中 一般不直接使用数组,也不直接使用带指针的数组,而是使用切片(Slice)
- 切片是对数组的一个视图,虽然Slice本身是值类型,但是它内部使用了对数组的指针引用,所以修改切片数据,会将数组原有数据修改掉
- Slice可以向后扩展,不能向前扩展,扩展规则为:s[i] 不可以超越len(s),向后扩展不可以超过cap(s)
- 向 Slice 添加元素
以下通过代码进行示例:
package main import "fmt" //数组的几种定义方式,数量要写在类型的前面 func array(){ var arr1 [5]int //普通定义方法,不定义初始值 arr2:=[3]int{1,2,3} //定义数组时设置初始值 arr3:=[...]int{2,4,6,8,10}//不指定长度,运行时让系统自己计算 var grid [4][5]int //定义二维数组 fmt.Println(arr1,arr2,arr3)//[0 0 0 0 0] [1 2 3] [2 4 6 8 10] fmt.Println(grid) //[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]] //遍历数组的方式 1 :普通用法 for i:=0;i<len(arr2);i++{ fmt.Println(arr2[i]) //分别输出 1,2,3 } //遍历数组的方式 1 :推荐用法用法(使用 range 关键字) for i,v:=range arr2 { fmt.Println(i,v) //0 1 //1 2 //2 3 } } //[]int 参数中没有指定数组长度,此时代表为 Slice func updateSlice(s []int) { s[0] = 100 } func slice() { arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7} //获取数组的中括号中使用区间,被称为切片 (Slice) //以下为切片的基础使用方式 //获取下标 2-6 之间的数值 fmt.Println("arr[2:6] =", arr[2:6]) //[2 3 4 5] //获取下标从开始到第6位的值 fmt.Println("arr[:6] =", arr[:6]) //[0 1 2 3 4 5] //获取下标从2到最后的值 fmt.Println("arr[2:] =", arr[2:]) //[2 3 4 5 6 7] //获取全部数据 fmt.Println("arr[:] =", arr[:]) //[0 1 2 3 4 5 6 7] //以下为Slice更多用法 s1 := arr[2:] fmt.Println("s1 =", s1) //s1 = [2 3 4 5 6 7] s2 := arr[:] fmt.Println("s2 =", s2) //s2 = [0 1 2 3 4 5 6 7] fmt.Println("After updateSlice(s1)") updateSlice(s1) //Slice 将原有数组的数据修改掉了 fmt.Println(s1) //[100 3 4 5 6 7] fmt.Println(arr) //[0 1 100 3 4 5 6 7] fmt.Println("After updateSlice(s2)") updateSlice(s2) //Slice 将原有数组的数据修改掉了 fmt.Println(s2) //[100 1 100 3 4 5 6 7] fmt.Println(arr) //[100 1 100 3 4 5 6 7] //对 Slice 再次进行 Slice 操作 fmt.Println("Reslice") fmt.Println(s2) //[100 1 100 3 4 5 6 7] s2 = s2[:5] fmt.Println(s2) //[100 1 100 3 4] s2 = s2[2:] fmt.Println(s2) //[100 3 4] //Slice 的扩展用法 fmt.Println("Extending slice") arr[0], arr[2] = 0, 2 //将数据复原 fmt.Println("arr =", arr) //arr = [0 1 2 3 4 5 6 7] s1 = arr[2:6] s2 = s1[3:5] // [s1[3], s1[4]] //此处通过扩展可以取到后面一个值 fmt.Printf("s1=%v, len(s1)=%d, cap(s1)=%d\n", s1, len(s1), cap(s1)) //s1=[2 3 4 5], len(s1)=4, cap(s1)=6 fmt.Printf("s2=%v, len(s2)=%d, cap(s2)=%d\n", s2, len(s2), cap(s2)) //s2=[5 6], len(s2)=2, cap(s2)=3 s3 := append(s2, 10) s4 := append(s3, 11) s5 := append(s4, 12) //添加元素时如果超过cap,系统会重新分配更大的底层数组 //由于值传递 的关系,必须手动接受 append 的返回值 fmt.Println("s3, s4, s5 =", s3, s4, s5) //s3, s4, s5 = [5 6 10] [5 6 10 11] [5 6 10 11 12] // s4 and s5 no longer view arr. fmt.Println("arr =", arr) //arr = [0 1 2 3 4 5 6 10] } func main() { array() slice() }
切片(Slice)的扩展
通过下图可以更好的理解 Slice的扩展功能,扩展后 s2=[5,6]。
Slice可以向后扩展,但不能向前扩展

Slice的底层实现包含了三个变量,分别是
ptr :代表当前Slice第一个数据在原数组中的指针
len:代表当前Slice的长度
cap:代表向后扩展后的总数据
