c语言编程笔录

首页 >   > 笔记大全

笔记大全

go语言扩容方法有哪些

更新时间:2023-12-21

什么是扩容

在Go中,slice是一个动态数组,可以动态分配和释放内存。但是,为了提高性能,slice可能会预分配比实际使用更多的空间。如果slice没有足够的空间存储元素,需要先重新分配更大的内存块,将现有元素复制到新的内存块中,然后释放旧内存块。这个过程称为扩容。

默认扩容方法

Go语言规范定义了一个默认的扩容策略,当slice的长度小于1024时,每次扩容将分配2倍的容量;当slice的长度大于等于1024时,则以1.25倍的比例进行扩容。Go语言通过内置函数cap()获取slice的容量,通过append()函数添加元素。

s := make([]int, 5, 10)
fmt.Println(len(s)) // 5
fmt.Println(cap(s)) // 10

s = append(s, 1)
fmt.Println(len(s)) // 6
fmt.Println(cap(s)) // 10

s = append(s, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
fmt.Println(len(s)) // 24
fmt.Println(cap(s)) // 40

手动设置扩容量

有时候,我们可能需要手动设置slice的扩容量(capacity),以减少内存分配的次数。可以通过内置函数make()的第三个参数来控制slice的容量。

s := make([]int, 5, 10)
fmt.Println(len(s)) // 5
fmt.Println(cap(s)) // 10

s = s[:7] // 手动设置为7
fmt.Println(len(s)) // 7
fmt.Println(cap(s)) // 10

扩容后增加固定大小

有些情况下,我们需要在扩容之后增加固定大小的元素个数。我们可以通过把新元素的数量与slice的当前容量相加,来计算需要分配的新内存块的大小。

s := []int{1, 2, 3}
fmt.Println(len(s)) // 3
fmt.Println(cap(s)) // 3

n := 5
if len(s)+n > cap(s) {
    newCap := (len(s) + n) * 2 // 计算需要分配的新内存块的大小
    newSlice := make([]int, len(s), newCap)
    copy(newSlice, s)
    s = newSlice
}
s = append(s, 4, 5, 6, 7, 8)
fmt.Println(len(s)) // 8
fmt.Println(cap(s)) // 10
总结:Go语言中,slice的扩容是一个常见的操作,可以通过append()函数和make()的第三个参数来实现。我们也可以手动设置slice的扩容量,以达到更好的内存管理和性能优化效果。