GO_复合类型---切片

📅 2026/7/11 21:28:28
GO_复合类型---切片
一、切片核心概念本质对底层数组的引用不是值类型是引用类型作用弥补数组长度固定的缺陷实现动态变长数组定义声明时不指定长度格式[]TT 为元素类型二、切片的创建方式4 种常用1. 从数组 / 切片截取最基础语法切片名 : 源数组/切片[low:high:max]low起始下标包含默认 0high结束下标不包含左闭右开默认末尾max容量上限默认等于底层数组容量长度公式len high - low容量公式cap max - lowgo// 示例 array : [...]int{10, 20, 30, 0, 0} // 固定长度数组 slice : array[0:3:5] // len3-03cap5-05元素[10,20,30]2. 自动推导类型创建go// 直接初始化切片长度元素个数容量长度 s1 : []int{1, 2, 3, 4, 5}3. make 函数创建开发最常用语法make([]T, len, cap)不指定容量cap len必须指定长度容量≥长度gos2 : make([]int, 5, 10) // len5cap10 s3 : make([]int, 5) // 无容量lencap5 s4 : []int{} // 空切片len0cap0三、切片的长度 (len) 和容量 (cap)长度 (len)切片中实际存储的元素个数容量 (cap)底层数组从起始位置到末尾的最大可存储元素个数决定扩容时机gofunc main() { a : []int{1, 2, 3, 0, 0} s : a[0:3:5] fmt.Println(len(s) , len(s)) // 3 fmt.Println(cap(s) , cap(s)) // 5 s2 : a[1:4:5] fmt.Println(len(s2) , len(s2)) // 3 (4-1) fmt.Println(cap(s2) , cap(s2)) // 4 (5-1) }四、切片截取操作常用简写goarray : []int{0,1,2,3,4,5,6} s1 : array[:] // 全量截取low0,highlen,capcap s2 : array[3:6] // 不写maxcap底层数组容量 s3 : array[:6] // 从0开始到下标6最常用 s4 : array[3:] // 从下标3开始到末尾五、切片与底层数组的关系核心重点切片共享底层数组修改切片元素会直接修改原数组 / 其他切片属于引用传递。gofunc main() { a : []int{0,1,2,3,4,5,6,7,8,9} s1 : a[2:5] // [2,3,4]引用a数组 // 修改切片元素 → 原数组同步修改 s1[1] 666 fmt.Println(s1 , s1) // [2,666,4] fmt.Println(a , a) // 原数组下标3变为666 // 切片再截取 → 仍共享底层数组 s2 : s1[2:7] // [4,5,6,7,8] s2[2] 777 fmt.Println(a , a) // 原数组下标6变为777 }六、append () 追加元素动态扩容append是切片动态扩容的核心函数超出容量时自动扩容。1. 基础用法gos1 : []int{} // 空切片 s1 append(s1, 1) // 追加单个元素 s1 append(s1, 2, 3) // 追加多个元素2. 扩容规则容量不足时默认以 2 倍容量扩容小切片扩容后会新建底层数组不再与原数组共享go// 验证扩容机制 func main() { s : make([]int, 0, 1) oldCap : cap(s) for i : 0; i 8; i { s append(s, i) if newCap : cap(s); oldCap newCap { fmt.Printf(cap: %d %d\n, oldCap, newCap) oldCap newCap } } } /* 输出 cap: 1 2 cap: 2 4 cap: 4 8 */七、copy () 切片复制解决切片共享底层数组的问题深拷贝两个切片完全独立。gofunc main() { srcSlice : []int{1, 2} // 源切片 dstSlice : []int{6,6,6,6} // 目标切片 copy(dstSlice, srcSlice) // 复制将源切片元素拷贝到目标切片 fmt.Println(dst , dstSlice) // [1,2,6,6] }八、切片作为函数参数切片是引用类型函数内修改切片外部原切片同步修改无需指针。实战切片初始化 冒泡排序goimport ( math/rand time ) // 初始化切片随机数赋值 func InitData(s []int) { rand.Seed(time.Now().UnixNano()) for i : 0; i len(s); i { s[i] rand.Intn(100) // 0-99随机数 } } // 冒泡排序切片做参数直接修改原切片 func BubbleSort(s []int) { n : len(s) for i : 0; i n-1; i { for j : 0; j n-i-1; j { if s[j] s[j1] { s[j], s[j1] s[j1], s[j] // 交换元素 } } } } func main() { // 创建切片 s : make([]int, 10) InitData(s) fmt.Println(排序前, s) BubbleSort(s) fmt.Println(排序后, s) }九、核心易错点总结切片不存储数据底层依赖数组是引用类型[low:high]是左闭右开不包含 high 下标元素lenhigh-lowcapmax-lowappend扩容后会新建底层数组断开与原数组的关联切片做函数参数传引用修改会影响原切片copy可以实现切片深拷贝避免共享数组总结切片是 Go 的动态数组专门解决数组长度固定的痛点开发优先用切片核心操作截取、append扩容、copy拷贝、函数传参核心原理引用底层数组扩容机制是 2 倍扩容实战中优先用make创建切片用append动态添加元素