iface与eface

iface与eface

iface与eface #

接口类型“动静兼备”的特性也决定了它的变量的内部表示绝不像一个静态类型变量(如 int、float64)那样简单,我们可以在 $GOROOT/src/runtime/runtime2.go中找到接口类型变量在运行时的表示:

// $GOROOT/src/runtime/runtime2.go
type iface struct {
    tab  *itab
    data unsafe.Pointer
}
type eface struct {
    _type *_type
    data  unsafe.Pointer
}

这两种表示分别用于不同的接口类型变量:

  1. eface结构 用于表示没有方法的空接口(empty interface)类型变量,也就是 interface{}类型的变量;
  2. iface结构 用于表示其余拥有方法的接口 interface 类型变量。

这两个结构的共同点是它们都有两个指针字段,并且第二个指针字段的功能相同,都是指向当前赋值给该接口类型变量的动态类型变量的值。

它们的不同点在于 eface 表示的空接口类型并没有方法列表,因此它的第一个指针字段指向一个_type类型结构。

而 iface 除了要存储动态类型信息之外,还要存储接口本身的信息(接口的类型信息、方法列表信息等)以及动态类型所实现的方法的信息,因此 iface 的第一个字段指向一个itab类型结构。

每个接口类型变量在运行时的表示都是由两部分组成的,针对不同接口类型我们可以简化记作:eface(_type, data)和iface(tab, data)。

Viewpoint #

From #

29|接口:为什么nil接口不等于nil?