详解 Go Interface 的数据结构
date
Mar 9, 2025
tags
编程
Go
slug
go-interface-data-structure
status
Published
summary
理解 interface 底层数据结构
type
Post
非原创,主要是对这篇文章的整理和反思。
对于 Go 中的 interface 变量,其结构由两个字组成,第一个字指向 interface table ,简称 itable,itable 中存储类型和接口对应的方法(函数指针),第二个字用来指向数据(变量)。
一般的,假设有代码:
在 32 位机器上,则有结构:

注意这里的 (*MyType).String 为什么看起来接收器是指针呢?因为对于 b,其在调用 String 方法时本质是以下代码:
b.tab->fun[0](b.data)
这里 b.data 是指针,所以尽管定义的值接收器,实际还是存储了引用接收器类型。(个人理解)Go 对于 interface 结构的两种优化
- interface 为空,也就是
interface{}
的情况下,第一个字直接指向类型,不再指向 itable。
- 数据可以直接存储在第二个字内,不需要间接指向时,第二个字可以直接存储数据
举个例子:
在 32 位机器上,一个字 32 位,1 是 int32 型,可以直接存储,再加上 interface{},两种优化叠加,结构如下:

itable 什么时候计算
在赋值或转换语句时计算,也就是运行时计算,此时 go runtime 对照接口和实际类型实现的方法确保接口所有的方法都已经实现(否则会在编译时就报错了),然后构造 itable 将方法加入 itable。
不难想到对照两组方法需要 O(m * n) 的时间复杂度,对两者排序可以优化到 O(m + n) 。
如上图 1 所示,itable 靠 (interface type, variable type) 来标识,后续需要使用可以直接使用,无需重复计算。