当使用类型为可变参数interface{}(例如Printf)的函数定义函数时,这些参数显然隐式转换为接口实例。
此转换是否暗示内存分配?这个转换快吗?如果担心代码效率,应该避免使用可变参数函数吗?
我发现的关于Go中接口内存分配的最佳解释仍然是来自Rus Cox(Go的核心程序员之一)的这篇文章。值得一读。
http://research.swtch.com/interfaces
我挑选了一些最有趣的部分:
存储在接口中的值可能任意大,但是只有一个字专用于保存接口结构中的值,因此该分配在堆上分配了一块内存,并将指针记录在一个字槽中。
...
Go编译器调用fmt.Printf(),生成从itable调用适当的函数指针的代码,并将接口值的数据字作为函数的第一个(在此示例中为唯一)参数传递。
Go的动态类型转换意味着编译器或链接器预先计算所有可能的itables是不合理的:对(接口类型,具体类型)对太多,并且不需要大多数。相反,编译器会为每种具体类型(例如Binary或int或func(map [int] string))生成类型描述结构。在其他元数据中,类型描述结构包含该类型实现的方法的列表。
...
接口运行时通过在具体类型的方法表中查找接口类型的方法表中列出的每个方法来计算可迭代性。运行时在生成它之后会对其进行缓存,因此该对应关系只需要计算一次。
...
如果所涉及的接口类型为空-它没有方法-那么itable除保留指向原始类型的指针外没有任何作用。在这种情况下,可以删除itable,并且值可以直接指向类型。
因为Go具有与动态方法查找一起使用的静态类型提示,所以它可以将查找从调用站点移回该值存储在界面中的位置。
| 归档时间: |
|
| 查看次数: |
1139 次 |
| 最近记录: |