由于golang中说interface的文章太多了,很多都已经说的很细节了,所以我再说感觉也有点难。于是总结出几个关键问题,供你参考,如果能做到准确无误有理有据的回答,那么interface应该是没有问题了。
type eface struct { // 16 bytes on a 64bit arch
_type *_type
data unsafe.Pointer
}
type iface struct { // 16 bytes on a 64bit arch
tab *itab
data unsafe.Pointer
}
type itab struct { // 40 bytes on a 64bit arch
inter *interfacetype
_type *_type
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.
}
type _type struct { // 48 bytes on a 64bit arch
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
}
https://draveness.me/golang/basic/golang-interface.html
tab结构是itab,里面包含了interfacetype,_type,fun,编译期生成。 https://github.com/teh-cmc/go-internals/blob/master/chapter2_interfaces/README.md
转空接口,很简单,将Eface中的data指针指向原型数据,type指针会指向数据的Type结构体。
与eface相同,但是需要赋值到itab,并且需要做检测,只有实现接口所有方法才可以进行转换。
那没话说,直接反射走起 有这样的语法解决v, ok := i.(T) 转换的时候也需要比较能否进行转换
两个interface是可以比较的, http://docs.studygolang.com/ref/spec#Comparison_operators 其中说到 Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil. 只要两个interface的动态类型相同和值相同就可以。
这个判断其实在检测的时候都需要用到。 检测就是看Type中的方法表是否包含了InterfaceType的方法表中的所有方法,并把Type方法表中的实现部分拷到Itab的func那张表中。其中表中的数据都是排序过的,所以对比起来快。 https://tiancaiamao.gitbooks.io/go-internals/content/zh/07.2.html