底层数据结构分析 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 类型包装器 取决于底层数据
相关推荐
平头哥AI17 小时前
Day 01 | go run 跑通第一个 Go 程序,go build 留下一个能拷走的 exe
开发语言·后端·golang
2601_9622965118 小时前
如何使用Golang包路径_管理本地和远程模块引用
golang·数据转换·变量定义·常用库·编程语言区别
wuyk55520 小时前
107.FreeRTOS 链表深度解析:从原理到面试满分答案
c语言·开发语言·数据结构·stm32·单片机·链表·面试
-dzk-20 小时前
【链表】LC 138.随机链表的复制
数据结构·链表
洋不写bug21 小时前
链表补充练习,双链表的模拟实现
java·数据结构·链表·双链表·底层实现
白狐_79821 小时前
408 数据结构|外部排序:流程与 k 路归并
数据结构·算法
影视飓风TIM1 天前
C++哈希表深度剖析:冲突处理、rehash、迭代器与unordered容器封装
c++·哈希算法·散列表
qq_246839751 天前
postgresql xxhash64 哈希函数实现
数据库·postgresql·哈希算法
FfHUCisI1 天前
GMP 调度器:Go 并发的心脏是如何跳动的
开发语言·golang·php
我不会起名字3221 天前
一天一道算法题(26):栈的简单应用
java·数据结构·python·算法·leetcode·golang·