底层数据结构分析 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 类型包装器 取决于底层数据
相关推荐
wabs6666 小时前
关于字符串【力扣344.反转字符串的思考】
数据结构·算法·leetcode
LuminousCPP6 小时前
数据结构基础篇(二):顺序表与链表全方位对比|从内存布局到 CPU 缓存理解底层差异
c语言·数据结构·经验分享·链表·缓存
有点。7 小时前
C++二叉树(一)
开发语言·数据结构·c++
报错小能手7 小时前
Go 语言结构 基础语法
开发语言·后端·golang
Lazionr7 小时前
stack与queue:底层实现与容器适配器
开发语言·数据结构·c++
剩下了什么8 小时前
go语言 Ctx:「错误三:在 Context 中存储可变值」
开发语言·后端·golang
原野池予8 小时前
深入Java集合框架:数组与List互转底层原理剖析(JDK 8)
java·数据结构·list
今日无bug9 小时前
列表转树:一道题搞懂 HashMap 在算法里的价值
前端·数据结构
运维开发笔记9 小时前
3.7 Go panic 与 recover 学习笔记
golang
忍冬k9 小时前
DeepSeek harness安装指南
java·开发语言·数据结构·c++·算法