Go 语言是如何实现切片扩容

简介: Go 语言是如何实现切片扩容

Go 语言中的切片(slice)是一个非常灵活的数据结构,它可以根据需求自动扩容。slice 的扩容机制如下:

  1. 初始容量:

    • 当使用 make([]T, len, cap) 创建 slice 时,可以指定初始长度 len 和容量 cap
    • 如果只指定长度,则容量默认等于长度。
  2. 添加元素时的扩容:

    • 当向 slice 中添加元素,并且当前容量不足时,Go 运行时会自动扩容。
    • 扩容策略是: 新容量 = 旧容量 + max(旧容量, 1)。
    • 也就是说,容量每次会至少翻倍,直到满足新增元素的需求。
  3. 扩容过程:

    • 分配一块新的连续内存空间,容量是旧容量的 1.5 倍或更大。
    • 将旧 slice 中的元素拷贝到新内存空间。
    • 更新 slice 的底层数组指针、长度和容量。
  4. 复制数据:

    • 扩容时会将旧 slice 中的数据完整地拷贝到新的内存空间。
    • 这意味着如果 slice 中的元素是指针或其他引用类型,那么这些引用也会被拷贝。

示例代码:

package main

import "fmt"

func main() {
   
    // 初始容量为 3
    s := make([]int, 0, 3)

    // 添加元素直到触发扩容
    for i := 0; i < 10; i++ {
   
        s = append(s, i)
        fmt.Printf("len=%d, cap=%d\n", len(s), cap(s))
    }
}

输出:

len=1, cap=3
len=2, cap=3
len=3, cap=3
len=4, cap=6
len=5, cap=6
len=6, cap=6
len=7, cap=9
len=8, cap=9
len=9, cap=9
len=10, cap=15

从输出中可以看到,slice 的容量每次都会增加一倍以上,直到满足新增元素的需求。这种扩容机制保证了 slice 的灵活性和性能。

相关文章
|
16天前
|
Go
go语言map、实现set
go语言map、实现set
26 0
|
2天前
|
JSON 测试技术 Go
零值在go语言和初始化数据
【7月更文挑战第10天】本文介绍在Go语言中如何初始化数据,未初始化的变量会有对应的零值:bool为`false`,int为`0`,byte和string为空,pointer、function、interface及channel为`nil`,slice和map也为`nil`。。本文档作为指南,帮助理解Go的数据结构和正确使用它们。
51 22
零值在go语言和初始化数据
|
4天前
|
安全 算法 程序员
在go语言中使用泛型和反射
【7月更文挑战第8天】本文介绍go支持泛型后,提升了代码复用,如操作切片、映射、通道的函数,以及自定义数据结构。 泛型适用于通用数据结构和函数,减少接口使用和类型断言。
62 1
在go语言中使用泛型和反射
|
6天前
|
缓存 编译器 Shell
回顾go语言基础中一些特别的概念
【7月更文挑战第6天】本文介绍Go语言基础涵盖包声明、导入、函数、变量、语句和表达式以及注释。零值可用类型如切片、互斥锁和缓冲,支持预分配容量以优化性能。
38 2
回顾go语言基础中一些特别的概念
|
10天前
|
存储 Go API
一个go语言编码的例子
【7月更文挑战第2天】本文介绍Go语言使用Unicode字符集和UTF-8编码。Go中,`unicode/utf8`包处理编码转换,如`EncodeRune`和`DecodeRune`。`golang.org/x/text`库支持更多编码转换,如GBK到UTF-8。编码规则覆盖7位至21位的不同长度码点。
109 1
一个go语言编码的例子
|
13天前
|
JSON 算法 测试技术
在go语言中调试程序
【6月更文挑战第29天】Go语言内置`testing`包支持单元测试、基准测试和模糊测试。`go test`命令可执行测试,如`-run`选择特定测试,`-bench`运行基准测试,`-fuzz`进行模糊测试。
36 2
在go语言中调试程序
|
2天前
|
JSON Java Go
Go 语言性能优化技巧
在Go语言中优化性能涉及数字字符串转换(如用`strconv.Itoa()`代替`fmt.Sprintf()`)、避免不必要的字符串到字节切片转换、预分配切片容量、使用`strings.Builder`拼接、有效利用并发(`goroutine`和`sync.WaitGroup`)、减少内存分配、对象重用(`sync.Pool`)、无锁编程、I/O缓冲、正则预编译和选择高效的序列化方法。这些策略能显著提升代码执行效率和系统资源利用率。
37 13
|
2天前
|
设计模式 Go
Go语言设计模式:使用Option模式简化类的初始化
在Go语言中,面对构造函数参数过多导致的复杂性问题,可以采用Option模式。Option模式通过函数选项提供灵活的配置,增强了构造函数的可读性和可扩展性。以`Foo`为例,通过定义如`WithName`、`WithAge`、`WithDB`等设置器函数,调用者可以选择性地传递所需参数,避免了记忆参数顺序和类型。这种模式提升了代码的维护性和灵活性,特别是在处理多配置场景时。
37 8
|
4天前
|
前端开发 JavaScript Go
|
2天前
|
存储 Go
go语言中fmt格式化包和内置函数汇总
【7月更文挑战第10天】本文介绍fmt包和`Errorf`用于创建格式化的错误消息。`fmt`包还涉及一些接口,如`Formatter`、`GoStringer`、`ScanState`、`Scanner`和`Stringer`,支持自定义格式化和输入/输出处理。
16 1