1. 接口的底层结构体
iface和eface,区别在于iface描述的接口包含方法,而eface则是不包含任何方法的空接口:interface{}
1.1 iface源码
type iface struct { tab *itab data unsafe.Pointer } type itab struct { inter *interfacetype _type *_type link *itab hash uint32 // copy of _type.hash. Used for type switches. bad bool // type does not implement interface inhash bool // has this itab been added to hash? unused [2]byte fun [1]uintptr // variable sized }
说明:iface内部维护两个指针,tab指向一个itab实体, 表示接口的类型以及赋给这个接口的实体类型。data指向接口具体的值,一般而言是一个指向堆内存的指针
interfacetype类型:
type interfacetype struct { typ _type pkgpath name mhdr []imethod }
iface结构体图示:
1.2 eface的源码
type eface struct { _type *_type // 动态类型 data unsafe.Pointer }
说明:eface维护了一个 _type 字段,表示空接口所承载的具体的实体类型,data描述了具体的值
举例:
f, _ := os.Open("text.txt") // f => *os.File var i1 interface{} i1 = f
说明:eface的data字段的值就是f,_type就是*os.File类型的元数据
验证:
func TestInterface(t *testing.T) { f, _ := os.Open("text.txt") fmt.Printf("f pointer:%p\n", f) fmt.Println("==========") var i1 interface{} i1 = f ptr2 := unsafe.Pointer(&i1) opt2 := (*[2]unsafe.Pointer)(ptr2) fmt.Println("interface: ", opt2[0], opt2[1]) }
输出:
f pointer:0xc00000e038 ========== interface: 0x11091e0 0xc00000e038
说明: i1的interface{}变量的data值与f的地址是一样的。
标签:iface,eface,type,接口,interface,data From: https://www.cnblogs.com/xiaojuzi1024/p/17765863.html