底层数据结构分析 go 语言中的 slice map channel interface

下面从 运行时(runtime)实现层面 ​ 系统分析 Go 语言中 slice、map、channel、interface​ 的底层数据结构(基于 Go 1.x 标准实现)。


1. slice(切片)

底层结构

复制代码
type slice struct {
    array unsafe.Pointer // 指向底层数组
    len   int             // 当前元素个数
    cap   int             // 底层数组容量
}

关键点

  • 非数组本身,只是一个描述符

  • 多个 slice 可共享同一个底层数组

  • 扩容规则:

    • cap < 1024:翻倍

    • cap ≥ 1024:按 ~25% 增长

  • 作为参数传递时,复制的是 slice 结构体,而非底层数组


2. map(哈希表)

底层结构

复制代码
type hmap struct {
    count     int    // 元素个数
    B         uint8  // bucket 数量为 2^B
    buckets   unsafe.Pointer
    oldbuckets unsafe.Pointer // 扩容时使用
    extra     *mapextra
}

bucket 结构

复制代码
type bmap struct {
    tophash [8]uint8
    keys    [8]keyType
    values  [8]valueType
    overflow *bmap
}

核心机制

  • 拉链法 + 溢出桶

  • 负载因子 ≈ 6.5

  • 渐进式扩容(incremental resizing)

  • key 必须可比较(==!=


3. channel(通道)

底层结构

复制代码
type hchan struct {
    qcount   uint           // 队列中元素数
    dataqsiz uint           // 环形缓冲区大小
    buf      unsafe.Pointer // 环形缓冲区
    elemsize uint16
    closed   uint32
    elemtype *_type
    sendx    uint           // 发送位置
    recvx    uint           // 接收位置
    recvq    waitq          // 接收等待队列
    sendq    waitq          // 发送等待队列
    lock     mutex
}

等待队列

复制代码
type waitq struct {
    first *sudog
    last  *sudog
}

特性

  • 支持 同步 / 异步 channel

  • 发送/接收阻塞时,goroutine 进入等待队列

  • close(chan)会唤醒所有等待者


4. interface(接口)

4.1 空接口 interface{}

复制代码
type eface struct {
    _type *_type      // 类型信息
    data  unsafe.Pointer // 数据指针
}

4.2 非空接口(带方法)

复制代码
type iface struct {
    tab  *itab
    data unsafe.Pointer
}

itab 结构

复制代码
type itab struct {
    inter *interfacetype // 接口类型
    _type *_type         // 具体类型
    hash  uint32
    fun   [1]uintptr     // 方法地址数组
}

关键区别

类型 组成
eface 类型 + 数据
iface 接口表 + 数据
  • 接口赋值发生 动态类型检查

  • 方法调用通过 虚表(vtable)


5. 总结对比

类型 本质 是否并发安全
slice 结构体 + 数组引用
map 哈希表
channel 带锁的队列
interface 类型包装器 取决于底层数据
相关推荐
CSharp精选营2 天前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
刘马想放假5 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠6 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
Darling噜啦啦13 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
小小工匠14 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾14 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
何以解忧,唯有..14 天前
Go语言循环语句详解:for、range与循环控制
开发语言·算法·golang
Qres82114 天前
算法复键——树状数组
数据结构·算法
踏着七彩祥云的小丑14 天前
Go学习第9天:并发编程 + 文件操作 + 正则表达式
学习·golang·正则表达式·go
JCGKS14 天前
Go `init` 函数:包初始化顺序到底是怎样的
golang·init·init执行顺序