底层数据结构分析 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 类型包装器 取决于底层数据
相关推荐
我不是懒洋洋4 小时前
【C++】类和对象( 类的定义、实例化、 this指针、 C++和C语言实现Stack对比)
c语言·开发语言·数据结构·c++·经验分享·算法·visual studio
XMYX-04 小时前
35 - Go 文件操作:读写与临时文件
golang
CryptoPP4 小时前
快速集成:基于现代API的金融数据流解决方案
大数据·数据结构·笔记·金融·区块链
YL200404264 小时前
054实现Trie(前缀树)
数据结构·leetcode
故事和你914 小时前
洛谷-【图论2-3】最小生成树1
开发语言·数据结构·c++·算法·动态规划·图论
故事和你914 小时前
洛谷-【图论2-3】最小生成树2
开发语言·数据结构·c++·算法·动态规划·图论
姚不倒4 小时前
Go语言实战:多态文件存储系统(接口、错误处理、panic/recover)
云原生·golang
玖釉-4 小时前
C++ 中的 buckets 详解:从哈希桶到 unordered_map 底层原理
算法·哈希算法·散列表
z200509304 小时前
今日算法(二叉树剪枝)
数据结构·c++·算法·剪枝