interface

1.interface

01.interface

1.1 interface作用

  • 接口是 Go 语言的重要组成部分,它在 Go 语言中通过一组方法指定了一个对象的行为

  • 接口 interface 的引入能够让我们在 Go 语言更好地组织并写出易于测试的代码

  • golang中的接口分为

    带方法的接口和空接口
    • iface:表示带方法的接口
    • eface:表示空接口

1.2 eface空接口

  • 空接口eface结构比较简单,由两个属性构成
  • 一个是类型信息_type,一个是数据信息
  • 其数据结构声明如下:
type eface struct {
  _type *_type
  data  unsafe.Pointer
}

img

  • 其中_type是GO语言中所有类型的公共描述,Go语言几乎所有的数据结构都可以抽象成 _type,是所有类型的公共描述
  • type负责决定data应该如何解释和操作
  • type的结构代码如下:
type _type struct {
  size       uintptr 
  ptrdata    uintptr    // size of memory prefix holding all pointers
  hash       uint32     // 类型哈希
  tflag      tflag
  align      uint8      // _type作为整体变量存放时的对齐字节数
  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  // type for pointer to this type, may be zero
}
  • data表示指向具体的实例数据,由于Go的参数传递规则为值传递
  • 如果希望可以通过interface对实例数据修改,则需要传入指针
  • 此时data指向的是指针的副本,但指针指向的实例地址不变,仍然可以对实例数据产生修改。

1.3 iface带方法的接口

  • iface 表示带方法的数据结构,非空接口初始化的过程就是初始化一个iface类型的结构
  • 其中data的作用同eface的相同,这里不再多加描述。
type iface struct {
  tab  *itab
  data unsafe.Pointer
}

img

  • iface结构中最重要的是itab结构(结构如下),每一个 itab 都占 32 字节的空间
  • itab可以理解为pair<interface type, concrete type>
  • itab里面包含了interface的一些关键信息,比如method的具体实现
type itab struct {
  inter  *interfacetype      // 接口自身的元信息
  _type  *_type           // 具体类型的元信息
  link   *itab
  bad    int32
  hash   int32           // _type里也有一个同样的hash,此处多放一个是为了方便运行接口断言
  fun    [1]uintptr        // 函数指针,指向具体类型所实现的方法
}

// interface type包含了一些关于interface本身的信息,比如package path,包含的method
type interfacetype struct {
  typ     _type
  pkgpath name
  mhdr    []imethod
}

type imethod struct {      //这里的 method 只是一种函数声明的抽象,比如  func Print() error
  name nameOff
  ityp typeOff
}

1.4 interface设计的优缺点

  • 优点,非侵入式设计,写起来更自由,无需显式实现,只要实现了与 interface 所包含的所有函数签名相同的方法即可。
  • 缺点,duck-typing风格并不关注接口的规则和含义,也没法检查,不确定某个struct具体实现了哪些interface。
  • 只能通过goru工具查看。

interface
http://coderedeng.github.io/2021/02/05/Go进阶 - interface/
作者
Evan Deng
发布于
2021年2月5日
许可协议