interface源码阅读

interface

interface的实现

所有interface,包括有方法和空接口,在内存中都是占据两个字长。那么在32位机器上就是8个字节,在64位机器上就是16个字节。

空interface的底层实现

在Go语言的源码位置: src\runtime\runtime2.go中

type eface struct {
    _type *_type        //类型指针
    data  unsafe.Pointer  //数据区域指针
} 

可以看到对于空的interface,其实就是两个指针。,先看第一个rtype类型, 这个就表示类型基本信息,包括类型的大小,对齐信息,类型的编号

type _type struct {
    size       uintptr         // 类型的大小
    ptrdata    uintptr      // size of memory prefix holding all pointers
    hash       uint32          // 类型的Hash值
    tflag      tflag              // 类型的Tags 
    align      uint8       // 结构体内对齐
    fieldalign uint8       // 结构体作为field时的对齐
    kind       uint8       // 类型编号 定义于runtime/typekind.go
    alg        *typeAlg    // 类型元方法 存储hash和equal两个操作。map key便使用key的_type.alg.hash(k)获取hash值
    gcdata    *byte            // GC相关信息
    str       nameOff   // 类型名字的偏移    
    ptrToThis typeOff    
}

非空interface的底层实现

type iface struct {
    tab  *itab
    data unsafe.Pointer
}

// 非空接口的类型信息 inter 是接口的定义 而剩下的是实际类型的定义 例如inter 中的method有 set和get两个 那在实例类型中的 fun里也有这两个

type itab struct {
    inter  *interfacetype    // 接口定义的类型信息
    _type  *_type                // 接口实际指向值的类型信息
    link   *itab  
    bad    int32
    inhash int32
    fun    [1]uintptr             // 接口方法实现列表,即函数地址列表,按字典序排序 这里是首地址
}

// 非空接口类型,接口定义,包路径等。

type interfacetype struct {
   typ     _type
   pkgpath name
   mhdr    []imethod      // 接口方法声明列表,按字典序排序
}
// 接口的方法声明 
type imethod struct {
   name nameOff          // 方法名
   ityp typeOff                // 描述方法参数返回值等细节
}

interface有两个重要点

1.赋值 将实际的值转化为interface
1.1 转化为 eface 也就是赋值给空接口 则直接根据 实际值进行内存分配 值拷贝等
1.2 转化为 iface 也就是赋值给有方法的接口 这个时候 会先更具 接口类型和实际类型 获取一个itab,这里会判断实际类型是否实现了接口 ,没有则获取失败。
注:系统会保存一个itab的hash表 通过 接口类型以及实际值的类型可以确定一个itab 也就是获取itab的时候 会先去hash表中找,找不到再生成添加进去 这样做是为了提升性能,不用每次都去判断生成itabl

2.断言 将interface转化为实际的值
判断转化的类型是否有实现接口的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值