内容简介:Go的interface源码在Golang源码的Go在不同版本之间的interface结构可能会有所不同,但是,整体的结构是不会改变的,此文章用的Go版本是1.11。Go的interface是由两种类型来实现的:
Go的interface源码在Golang源码的 runtime 目录中。
Go在不同版本之间的interface结构可能会有所不同,但是,整体的结构是不会改变的,此文章用的 Go 版本是1.11。
Go的interface是由两种类型来实现的: iface 和 eface 。
其中, iface 表示的是包含方法的interface,例如:
type Person interface {
Print()
}
而 eface 代表的是不包含方法的interface,即
type Person interface {}
或者
var person interface{} = xxxx实体
eface
eface 的具体结构是:
一共有两个属性构成,一个是类型信息 _type ,一个是数据信息。
其中, _type 可以认为是Go语言中所有类型的公共描述,Go语言中几乎所有的数据结构都可以抽象成 _type ,是所有类型的表现,可以说是万能类型,
data 是指向具体数据的指针。
type 的具体代码为:
type _type struct {
size uintptr
ptrdata uintptr // size of memory prefix holding all pointers
hash uint32
tflag tflag
align uint8
fieldalign uint8
kind uint8
alg *typeAlg
// gcdata stores the GC type data for the garbage collector.
// If the KindGCProg bit is set in kind, gcdata is a GC program.
// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
gcdata *byte
str nameOff
ptrToThis typeOff
}
eface 的整体结构是:
对于没有方法的interface赋值后的内部结构是怎样的呢?
可以先看段代码:
import (
"fmt"
"strconv"
)
type Binary uint64
func main() {
b := Binary(200)
any := (interface{})(b)
fmt.Println(any)
}
输出200,赋值后的结构图是这样的:
对于将不同类型转化成 type 万能结构的方法,是运行时的 convT2E 方法,在 runtime 包中。
以上,是对于没有方法的接口说明。
对于包含方法的函数,用到的是另外的一种结构,叫 iface
iface
所有包含方法的接口,都会使用 iface 结构。包含方法的接口就是一下这种最常见,最普通的接口:
type Person interface {
Print()
}
iface 的源代码是:
type iface struct {
tab *itab
data unsafe.Pointer
}
iface 的具体结构是:
itab 是 iface 不同于 eface 比较关键的数据结构。其可包含两部分:一部分是确定唯一的包含方法的interface的具体结构类型,一部分是指向具体方法集的指针。
具体结构为:
属性 itab 的源代码是:
type itab struct {
inter *interfacetype //此属性用于定位到具体interface
_type *_type //此属性用于定位到具体interface
hash uint32 // copy of _type.hash. Used for type switches.
_ [4]byte
fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
}
属性 interfacetype 类似于 _type ,其作用就是interface的公共描述,类似的还有 maptype 、 arraytype 、 chantype …其都是各个结构的公共描述,可以理解为一种外在的表现信息。 interfacetype 源码如下:
type interfacetype struct {
typ _type
pkgpath name
mhdr []imethod
}
type imethod struct {
name nameOff
ityp typeOff
}
iface 的整体结构为:
对于含有方法的interface赋值后的内部结构是怎样的呢?
一下代码运行后
package main
import (
"fmt"
"strconv"
)
type Binary uint64
func (i Binary)String()string {
return strconv.FormatUint(i.Get(), 10)
}
func (i Binary)Get()uint64 {
return uint64(i)
}
func main() {
b := Binary(200)
any := fmt.Stringer(b)
fmt.Println(any)
}
首先,要知道代码运行结果为:200。
其次,了解到 fmt.Stringer 是一个包含 String 方法的接口。
type Stringer interface {
String() string
}
最后,赋值后接口 Stringer 的内部结构为:
对于将不同类型转化成itable中 type(Binary) 的方法,是运行时的 convT2I 方法,在 runtime 包中。
参考文献:
《Go in action》
https://research.swtch.com/interfaces
https://juejin.im/entry/5a7d08d3f265da4e865a6200以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java核心技术·卷 I(原书第10版)
[美] 凯.S.霍斯特曼(Cay S. Horstmann) / 周立新 等 / 机械工业出版社 / 2016-9 / CNY 119.00
Java领域最有影响力和价值的著作之一,由拥有20多年教学与研究经验的资深Java技术专家撰写(获Jolt大奖),与《Java编程思想》齐名,10余年全球畅销不衰,广受好评。第10版根据Java SE 8全面更新,同时修正了第9版中的不足,系统全面讲解了Java语言的核 心概念、语法、重要特性和开发方法,包含大量案例,实践性强。 一直以来,《Java核心技术》都被认为是面向高级程序员的经典教......一起来看看 《Java核心技术·卷 I(原书第10版)》 这本书的介绍吧!