package main import "fmt" func main() { /* 声明与赋值 */ // 1. 声明切片, 切片不是一个值,是一个boxed结构体, array unsafe.Pointer // 数组指针 // 底层数组的长度: 容量10, 当前有几个元素3 // 需要考虑性能时,这个常用 slice1 := make([]int, 3, 5) fmt.Println(slice1, len(slice1), cap(slice1)) // 底层数组的长度: 容量10, 当前有几个元素3 slice1 = append(slice1, 4, 5) fmt.Println(slice1, len(slice1), cap(slice1)) // 这里的容器, 不是硬性限制,是超过容量后,底层数组是自动扩容的(重要) // 扩容: 一般是原来的2倍, 新申请一块更大的数组, 把老数据copy过去 slice1 = append(slice1, 6) fmt.Println(slice1, len(slice1), cap(slice1)) // 2. 声明并赋值 (不常用) var slice2 []int slice2 = []int{1, 2, 3, 4, 5} fmt.Println(slice2, len(slice2), cap(slice2)) // 3. 声明赋值放在一起 (常用) var slice3 []int = []int{1, 2, 3, 4, 5} fmt.Println(slice3, len(slice3), cap(slice3)) // 4. 快捷声明赋值 (常用) slice4 := []int{1, 2, 3, 4, 5} fmt.Println(slice4, len(slice4), cap(slice4)) /* 切片的访问 1. 通过下标(元素的索引)访问切片元素 2. 元素值修改,直接通过下标赋值即可 */ fmt.Println("slice4[0]=", slice4[0]) slice4[0] = 100 fmt.Println("slice4[0]=", slice4[0]) /* 切片中添加元素 append(切片变量, 元素1, 元素2, ...) 注意append 后 是参数一个新的切片变量, 所以要接收返回值 动作: 申请了新的底层数组, 把老数据copy过去, 然后添加新的元素 append的元素如果超过容器,会触发地址扩容, 新的数组 */ slice4_v2 := append(slice4, 6, 7, 8) fmt.Println("slice4:", slice4, len(slice4), cap(slice4)) fmt.Println("slice4_v2:", slice4_v2, len(slice4_v2), cap(slice4_v2)) /* 1. nil 切片: 没有分配内存(array指针是nil), 长度和容量都是0 2. 空切片 切片时一个应用类型(盒子) */ var slice5 []int // nil 切片 fmt.Println(slice5, len(slice5), cap(slice5)) slice5 = append(slice5, 10, 11, 12) fmt.Println(slice5, len(slice5), cap(slice5)) slice6 := []int{} // 空切片 fmt.Println(slice6, len(slice6), cap(slice6)) slice6 = append(slice6, 10) fmt.Println(slice6, len(slice6), cap(slice6)) /* 切片的遍历 1. for 循环遍历, 实际上遍历的也是底层的数组 2. for range 遍历 */ fmt.Println("== 切片的遍历: for ==") for i := 0; i < len(slice4_v2); i++ { fmt.Printf("slice4_v2[%d]=%d\n", i, slice4_v2[i]) } fmt.Println("== 切片的遍历: for range (推荐) ==") for index, value := range slice4_v2 { fmt.Printf("slice4_v2[%d]=%d\n", index, value) } /* 切片是一种引用类型 注意: 数组是引用类型吗? 不是 1. 如果是数组: 是2块隔离的内存地址空间(线性分配) 2. 如果是切片: 底层数组是同一块内存地址空间 浅拷贝: 赋值 底层数据没有copy一份, 还是指向同一块内存地址空间 */ fmt.Println("== 切片是一种引用类型 ==") slice7 := []int{1, 2, 3} slice8 := slice7 fmt.Println("slice7:", slice7) fmt.Println("slice8:", slice8) slice8[0] = 1000 fmt.Println("slice7:", slice7) fmt.Println("slice8:", slice8) /* 切片的拷贝 如果希望把 底层arry里面的数据copy到另一个切片中 使用内置函数: copy(目标切片, 源切片) 深拷贝: 底层数据已copy一份 申请一片新的内存来存储这个值 */ fmt.Println("== 切片的拷贝 ==") slice9 := make([]int, len(slice7)) copy(slice9, slice7) fmt.Println("slice9:", slice9) slice9[0] = 2000 fmt.Println("slice7:", slice7) fmt.Println("slice9:", slice9) }