文章目录
前言
本文主要记录:
1.Slice切片的实现原理。
2.切片的指针是存储在堆中还是栈中的。
3.切片使用中的一些坑。
一、为什么要有切片?
由于go中的数组是值类型的,使用的时候是固定大小的 如arr := [3]int{1,2,3} 之后就无法再改变数组的长度了。
所以golang基于数组设计出了以动态数组为底层数据结构的切片Slice。动态数组就是一种可以动态往数组中添加、删除元素的数据结构,并且在容量不足的时候可以动态的进行扩容。
二、切片是怎么实现的呢?
1.Go的切片结构体 – SliceHeader
如下图所示,go使用SliceHeader这个struct来表示动态数组,它包含了一个Data 的uint类型的指针用于指向底层动态数组的地址、Len表示切片中保存的元素个数、Cap表示当前数组内总共有多少容量。
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
2.初始化切片的两种方式
切片初始化的方式分为 编译期初始化 和 运行时初始化两种方式:
编译期初始化包括了: 1)从数组中生成切片 2)使用字面量的方式生成切片
// 演示go语言切片相关操作
// slice初始化的方式一: []string{}
slice1 := []string{
"java", "golang", "python", "php"}
fmt.Println(slice1) // [java golang python php]
// slice初始化的方式二: 使用make() 函数 很常用!
slice2 := make([]string, 5)
fmt.Println(len(slice2)) // 5
fmt.Println(slice2) //[ ] 默认是5个空字符串
// slice初始化的方式三: 通过数组来创建
data_arr := [5]int{
2,4,6,8,10}

本文探讨Go语言中切片Slice的实现原理,包括SliceHeader结构体、初始化方式、内存分配以及切片扩容的细节。还介绍了切片使用时的常见陷阱,如切片共享、append操作及大切片性能问题。通过学习,有助于理解和高效利用切片进行开发。
2173

被折叠的 条评论
为什么被折叠?



