iface 和 eface 都是 Go 中描述接口的底层结构体,区别在于 iface 描述的接口包含方法,而 eface 则是不包含任何方法的空接口:interface{}。
从源码层面看一下:
typeifacestruct { tab *itab data unsafe.Pointer}typeitabstruct { 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}
packagemainimport"fmt"funcmain() { x :=200var any interface{} = x fmt.Println(any) g :=Gopher{"Go"}var c coder= g fmt.Println(c)}typecoderinterface {code()debug()}typeGopherstruct { language string}func (p Gopher) code() { fmt.Printf("I am coding %s language\n", p.language)}func (p Gopher) debug() { fmt.Printf("I am debuging %s language\n", p.language)}
执行命令,打印出汇编语言:
go tool compile -S ./src/main.go
可以看到,main 函数里调用了两个函数:
func convT2E64(t *_type, elem unsafe.Pointer) (e eface)
func convT2I(tab *itab, elem unsafe.Pointer) (i iface)
typearraytypestruct { typ _type elem *_type slice *_type len uintptr}typechantypestruct { typ _type elem *_type dir uintptr}typeslicetypestruct { typ _type elem *_type}typestructtypestruct { typ _type pkgPath name fields []structfield}