源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Golang 内存模型详解(一)

  • 时间:2020-12-24 15:12 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Golang 内存模型详解(一)
[b]开始之前[/b] 首先,这是一篇菜B写的文章,可能会有理解错误的地方,发现错误请斧正,谢谢。 为了治疗我的懒癌早期,我一次就不写得太多了,这个系列想写很久了,每次都是开了个头就没有再写。这次争取把写完,弄成一个系列。 [b]此 nil 不等彼 nil[/b] 先声明,这个标题有标题党的嫌疑。 Go 的类型系统是比较奇葩的,nil 的含义跟其它语言有些差别,这里举个例子(可以直接进入 [url=http://play.golang.org/p/ezFhXX0dnB]http://play.golang.org/p/ezFhXX0dnB[/url] 运行查看结果):
[url=http://golang.org/doc/faq#nil_error]http://golang.org/doc/faq#nil_error[/url])。 简单的说就是 nil 代表 “zero value”(空值),对于不同类型,它具体所代表的值不同。比如上面的 a 为“*A 类型的空值”,而 ai 为“interface{} 类型的空值”。造成理解失误的最大问题在于,struct pointer 到 interface 有隐式转换(var ai interface{] = a,这里有个隐式转换),至于为什么对于 Go 这种在其它转换方面要求严格,而对于 interface 要除外呢,for convenience 吧,呵呵…… 碰到了这个坑,我就开始好奇了,Go 的类型系统到底是什么样的? [b]Go 内存模型 - interface[/b] 概述 为了读懂下面的内容,你需要: 了解 C、Go 语言 Go 1.3 源代码 ([url=https://go.googlecode.com/archive/go1.3.zip]https://go.googlecode.com/archive/go1.3.zip[/url]) PS: 由于 Go 用到了 Plan9 C 这个小众的C编译器的扩展,比如在函数签名中使用 · 字符以区分 package/function(比如runtime·panic),这对理解不会产生什么影响。 PSS: 对于 Go runtime,可以参考src/pkg/reflect(reflect包)中的的代码,对类型系统的实现的理解有帮助。 Go 语言的类型定义可以在 src/pkg/runtime/ 目录下找到,主要由以下几个文件构成: 1.runtime.h 2.type.h 对于 interface 类型,主要看下面几个结构体定义: 1.InterfaceType 2.Itab 3.Iface 4.Eface 它们的C语言定义如下 (可以在 runtime.h 中找到): [b]InterfaceType:[/b] 代表了总的 interface 类型,其中: 1.Type: 类型描述,所有的类型都有这个类型描述(比如 array, map, slice) 2.mhdr 以及 m: interface 接口方法列表
[u]复制代码[/u] 代码如下:
struct InterfaceType {     Type;     Slice mhdr;     IMethod m[]; };
[b]Itab:[/b] 类似于虚函数表,该表不会被GC回收,其中: 1.inter: 指向具体的 interface 类型 2.type: 具体实现类型, 也即 receiver type 3.link: 指向下一个函数表,因为 interface 可以 embed 多个 interface,因此实现为一个链表形式 4.bad: <略> 5.unsued: <略> 6.fun: 函数列表,每个元素是一个指向具体函数实现的指针
[u]复制代码[/u] 代码如下:
struct  Itab {     InterfaceType*  inter;     Type*   type;     Itab*   link;     int32   bad;     int32   unused;     void    (*fun[])(void); };
[b]Iface:[/b] 该类型为一般的 interface 类型所对应的数据结构,其中: 1.tab: 参见 Itab 的说明,尤其是 Itab::link 2.data: 指向具体数据(比如指向struct,当然,如果一个数据不超过一个字长,那么这个data就可以直接存放,不需要指针再做以及跳转)
[u]复制代码[/u] 代码如下:
struct Iface {     Itab*   tab;     void*   data; };
[b]Eface:[/b] 该类型为 interface{} (empty interface) 所对应的数据结构,其中: 1.type: 具体实现类型, 也即 receiver type 2.data: 同 Iface
[u]复制代码[/u] 代码如下:
struct Eface {     Type*   type;     void*   data; };
他们的依赖关系如下图所示: [img]http://files.jb51.net/file_images/article/201410/20141027114824981.png?201492711490[/img] 先到这里,下一篇将会举例子说明给一个 interface{} 类型的变量赋值后,其具体的内存结构是怎么样的。 打了几个小时,真费时间,争取这个系列不坑 (逃
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部