news 2026/5/30 14:57:49

Go interface 底层的 itab 到底是什么

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Go interface 底层的 itab 到底是什么

你已经知道:

typeAnimalinterface{Speak()string}typeDogstruct{}func(d Dog)Speak()string{return"汪汪"}

这里:

Animal = 接口 Dog = 结构体 Speak = 方法

那么:

Go 到底是怎么知道:

vara Animal=Dog{}

里面的 Dog 实现了 Animal?

又是怎么找到:

a.Speak()

应该调用哪个函数的?

答案:

就是:

itab

一、先看这段代码

typeAnimalinterface{Speak()string}typeDogstruct{}func(d Dog)Speak()string{return"汪汪"}funcmain(){vara Animal a=Dog{}fmt.Println(a.Speak())}

输出:

汪汪

二、问题来了

变量:

a

类型是:

Animal

但是:

真正装进去的是:

Dog{}

那么:

执行:

a.Speak()

的时候:

Go 怎么知道:

应该去调用:

Dog.Speak()

而不是:

Cat.Speak()

呢?


三、interface 底层结构

前面讲过:

interface 本质:

(Type, Value)

例如:

vara Animal=Dog{}

底层:

大概是:

T = Dog V = Dog{}

四、但仅仅有类型还不够

因为:

Go 还需要知道:

这个类型实现了哪些接口方法

例如:

Dog ↓ Speak() ↓ 对应哪个函数地址

五、于是出现了 itab

itab:

全称:

interface table

翻译:

接口方法表

六、itab 是干什么的

一句话:

记录 某个具体类型 如何实现某个接口

七、画图理解

例如:

vara Animal=Dog{}

底层:

大概这样:

a │ ├── itab │ └── data

八、data

data:

保存:

真正的数据

也就是:

Dog{}

九、itab

itab:

保存:

接口信息 + 具体类型信息 + 方法地址

十、对应到你的代码


接口类型

typeAnimalinterface{Speak()string}

对应:

Animal

具体类型

typeDogstruct{}

对应:

Dog

方法实现

func(d Dog)Speak()string

对应:

Dog.Speak()

十一、itab 里面存什么

大概可以理解成:

itab ├── interface type ├── concrete type └── method table

具体:

itab ├── Animal ├── Dog └── Dog.Speak()

十二、画成表

项目对应
interface typeAnimal
concrete typeDog
methodDog.Speak

十三、执行 a.Speak() 时发生什么

代码:

a.Speak()

Go:

先找到:

a.itab

然后:

在里面找到:

Speak 对应的函数地址

最终调用:

Dog.Speak()

十四、整个过程

a.Speak() ↓ 找到 itab ↓ 找到 Speak 函数地址 ↓ 执行 Dog.Speak() ↓ 返回 汪汪

十五、为什么接口调用比普通调用慢一点

普通调用:

dog.Speak()

编译时:

就知道:

调用哪个函数

接口调用:

a.Speak()

需要:

先查 itab 再跳转函数

所以:

会多一步。


十六、再举一个例子

typeCatstruct{}func(c Cat)Speak()string{return"喵喵"}

此时:

vara Animal=Cat{}

底层:

变成:

itab ├── Animal ├── Cat └── Cat.Speak()

十七、为什么不用提前写 implements

Java:

classDogimplementsAnimal

Go:

不用。

因为:

Go 编译器:

会自动检查:

Dog 有没有实现 Animal 的全部方法

如果有:

自动生成:

Animal-Dog 的 itab

十八、编译器什么时候创建 itab

当你写:

vara Animal=Dog{}

时。


编译器发现:

Dog 实现了 Animal

于是:

创建:

Animal ↔ Dog

对应的 itab。


十九、为什么接口断言能成功

例如:

vara Animal=Dog{}

执行:

dog:=a.(Dog)

Go:

会看:

itab 里的 concrete type

发现:

Dog

于是:

断言成功。


二十、结合 interface = (Type, Value) 再理解

很多教程说:

interface = (Type, Value)

其实:

更准确:

应该理解成:

interface ├── itab └── data

其中:


data

保存:

真正的数据

例如:

Dog{}

itab

保存:

Dog 的类型 Animal 的信息 Dog.Speak 的地址

二十一、最终完整图(重点)

var a Animal = Dog{}

底层:

a │ ├── itab │ ├── interface type : Animal │ ├── concrete type : Dog │ └── method table │ └── Speak → Dog.Speak │ └── data └── Dog{}

二十二、最后一句总结(必须记住)

itab 本质:

接口方法映射表

作用:

记录 某个具体类型 如何实现某个接口

在你的例子里:

Animal ← 接口类型 Dog ← 具体类型 Dog.Speak ← 方法实现

Go 会生成:

itab ├── Animal ├── Dog └── Speak → Dog.Speak

当执行:

a.Speak()

时:

实际上:

就是:

通过 itab 找到 Dog.Speak() 再调用

所以:

interface 能装不同类型 却还能正确调用对应方法

核心秘密:

就是:

itab + data
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/30 14:50:07

如何用智能脚本彻底解决Windows和Office激活难题

如何用智能脚本彻底解决Windows和Office激活难题 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为系统激活状态不稳定而烦恼吗?当Windows突然提示"需要激活"&#xf…

作者头像 李华
网站建设 2026/5/30 14:49:14

合同比对工具怎么选?Word、PDF 和扫描件差异对比思路

合同版本对比,看起来像是“找不同”,实际做起来经常没那么简单。两份 Word 合同,修订记录完整,篇幅也不长,用 Word 自带比较功能通常能解决不少问题。但企业日常处理的合同,往往不是这么理想:客…

作者头像 李华
网站建设 2026/5/30 14:46:04

卖报关报检服务怎么找客户?有进出口业务的工厂在哪里

上个月帮一个做报关代理的朋友梳理了他的客户结构。他手上有三四十家稳定客户,大部分是深圳保税区附近的加工贸易厂,靠熟人介绍维系了几年,但每次说要系统拓展新客户,都卡在同一个问题上:全国有进出口业务的工厂那么多…

作者头像 李华
网站建设 2026/5/30 14:46:01

卖工厂 ERP/MES 实施服务怎么找客户?下游工厂在哪里

做了一个工厂数字化实施服务的下游版图研究,整理下来供参考。 研究的对象不是采购系统的大企业 IT 部,而是有车间、有工序、正在被排产和追溯问题折磨的中型制造工厂。这批工厂的规模有明确上下限,需求按制造类型高度分化,地理上又…

作者头像 李华