分享
  1. 首页
  2. 文章

Go语言interface底层实现

互联网技术窝 · · 2248 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Go的interface源码在Golang源码的 runtime目录中。 Go在不同版本之间的interface结构可能会有所不同,但是,整体的结构是不会改变的,此文章用的Go版本是1.11。

Go的interface是由两种类型来实现的: ifaceeface。 其中, iface表示的是包含方法的interface,例如:

  1. type Personinterface{

  2. Print()

  3. }

eface代表的是不包含方法的interface,即

  1. type Personinterface{}

或者

  1. var person interface{}= xxxx实体

eface

eface的具体结构是:

一共有两个属性构成,一个是类型信息 _type,一个是数据信息。 其中, _type可以认为是Go语言中所有类型的公共描述,Go语言中几乎所有的数据结构都可以抽象成 _type,是所有类型的表现,可以说是万能类型, data是指向具体数据的指针。

type的具体代码为:

  1. type _type struct{

  2. size uintptr

  3. ptrdata uintptr // size of memory prefix holding all pointers

  4. hash uint32

  5. tflag tflag

  6. align uint8

  7. fieldalign uint8

  8. kind uint8

  9. alg *typeAlg

  10. // gcdata stores the GC type data for the garbage collector.

  11. // If the KindGCProg bit is set in kind, gcdata is a GC program.

  12. // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.

  13. gcdata *byte

  14. str nameOff

  15. ptrToThis typeOff

  16. }

eface的整体结构是:

对于没有方法的interface赋值后的内部结构是怎样的呢? 可以先看段代码:

  1. import(

  2. "fmt"

  3. "strconv"

  4. )

  5. type Binary uint64

  6. func main(){

  7. b :=Binary(200)

  8. any :=(interface{})(b)

  9. fmt.Println(any)

  10. }

输出200,赋值后的结构图是这样的:

对于将不同类型转化成 type万能结构的方法,是运行时的 convT2E方法,在 runtime包中。 以上,是对于没有方法的接口说明。 对于包含方法的函数,用到的是另外的一种结构,叫 iface

iface

所有包含方法的接口,都会使用 iface结构。包含方法的接口就是一下这种最常见,最普通的接口:

  1. type Personinterface{

  2. Print()

  3. }

iface的源代码是:

  1. type iface struct{

  2. tab *itab

  3. data unsafe.Pointer

  4. }

iface的具体结构是:

itabiface不同于 eface比较关键的数据结构。其可包含两部分:一部分是确定唯一的包含方法的interface的具体结构类型,一部分是指向具体方法集的指针。 具体结构为:属性 itab的源代码是:

  1. type itab struct{

  2. inter *interfacetype //此属性用于定位到具体interface

  3. _type *_type //此属性用于定位到具体interface

  4. hash uint32 // copy of _type.hash. Used for type switches.

  5. _ [4]byte

  6. fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.

  7. }

属性 interfacetype类似于 _type,其作用就是interface的公共描述,类似的还有 maptypearraytypechantype...其都是各个结构的公共描述,可以理解为一种外在的表现信息。 interfacetype源码如下:

  1. type interfacetype struct{

  2. typ _type

  3. pkgpath name

  4. mhdr []imethod

  5. }

  6. type imethod struct{

  7. name nameOff

  8. ityp typeOff

  9. }

iface的整体结构为:

对于含有方法的interface赋值后的内部结构是怎样的呢? 一下代码运行后

  1. package main

  2. import(

  3. "fmt"

  4. "strconv"

  5. )

  6. type Binary uint64

  7. func (i Binary)String()string{

  8. return strconv.FormatUint(i.Get(),10)

  9. }

  10. func (i Binary)Get() uint64 {

  11. return uint64(i)

  12. }

  13. func main(){

  14. b :=Binary(200)

  15. any := fmt.Stringer(b)

  16. fmt.Println(any)

  17. }

首先,要知道代码运行结果为:200。 其次,了解到 fmt.Stringer是一个包含 String方法的接口。

  1. type Stringerinterface{

  2. String()string

  3. }

最后,赋值后接口 Stringer的内部结构为:

对于将不同类型转化成itable中 type(Binary)的方法,是运行时的 convT2I方法,在 runtime包中。


有疑问加站长微信联系(非本文作者)

本文来自:微信公众平台

感谢作者:互联网技术窝

查看原文:Go语言interface底层实现

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2248 次点击
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏