Go Slice 使用中的小陷阱
go中的切片有两个特性:
- 底层的数据结构是数组
type slice struct {
array unsafe.Pointer
len int
cap int
}
包括从切片和数组派生出来的切片都是公用一个底层数组的
- 当往切片append的元素超过容量时,即len(s) < cap(s)时,底层的数组会重新分配一个容量更大的数组。
- make构造出来的切片,已经预先填充了len个零值元素了。
总而言之,对切片的更改都会影响到底层的数组结构,因此需要慎重。
动手做个实验:
package main
import (
"fmt"
)
func double(s []int, count int) {
fmt.Println("函数调用内切片的长度为", len(s), " 容量为", cap(s))
for i:=0; i < count; i++ {
s = append(s, 100)
}
for i, v := range s {
s[i] = v * 2
}
}
func main() {
s := make([]int, 5, 10)
// 下面的赋值会改变s的底层数组,导致上面指定的容量10失效
// s = []int{
// 1, 2, 3, 4, 5,
// }
for i:=0; i < 5; i++ {
s[i] = i + 1
}
fmt.Println("主函数内切片的长度为", len(s), " 容量为", cap(s))
fmt.Println(s)
double(s, 1)
fmt.Println(s)
// 添加超过切片容量的元素后,double函数内切片底层的数组重新分配了,和主函数外的切片的底层数组不是同一个了,因此对其修改不会影响到主函数切片的数值
double(s, 10)
fmt.Println(s)
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署