Go1.23 新特性:新库 structs.HostLayout,终于可以指定内存布局了!

大家好,我是煎鱼。

在 Go 这一门编程语言中,我们时常会看到一些 Go 面试题或结构体的知识讲解,主要是针对内存对齐这一块的知识点。

这次 Go1.23 新版本中也针对这块进行了一些补全,分享给大家,一起学习和进步!

f5a63e061d9cc18524e29ac4e3550cd7.png

背景

Go 在对于结构体(struct)的布局规则描述得相当简略。在现实环境中,大多数都是由需要准备面试的同学、感兴趣的同学研究后分析在社区内分享出来。

但在实践中,由于结构体在极少数情况下需要与平台 API 进行交互,Go 的实现被严格限制,必须遵循平台的布局和对齐规则。

当这些规则与 Go 的默认设置不一致时,例如:ppc64le 平台上,float64 字段的平台对齐方式与 Go 默认的对齐方式不同,就可能引发兼容性问题。

这种情况迫使 Go 在那些约束条件与其它平台常见的情况不同的平台上需要做出权衡,可能会阻碍了节省内存和提高垃圾回收效率的字段重新排序优化。

Go1.23 新标准库 structs

本次 Go1.23 新增了一个标准库 structs,与 strings、bytes 和 slices 几个库并行,本次有着特殊的使用作用。

a4526aecff87cf5a87f978ebd5d48ade.png

这个新库现阶段只有一个东西,那就是核心的 HostLayout 结构体:

package structs

// HostLayout, as a field type, signals that the size, alignment,
// and order of fields conform to requirements of the host
// platform and may not match the Go compiler’s defaults.
type HostLayout struct {}

HostLayout 用于声明和指定结构体采用主机的内存布局方式。当结构体包含 HostLayout 类型的字段时,其在内存中的布局将遵循主机的期望,一般与主机的 C 应用二进制接口(ABI)保持一致

值得注意的是,HostLayout 仅影响其所在的结构体本身的布局,而不影响结构体内部其他结构体字段的布局,也不会影响包含这种特殊布局结构体的其他结构体。

本次新增加的 HostLayout 将会作为字段类型使用,该字段在使用时建议命名为下划线("_"),并放在结构体定义的最开始位置。

具体的用法例子,如下代码:

// 通过 HostLayout 指定结构体布局方式
type HasHostLayout struct {
    _ structs.HostLayout
   // 煎鱼正在干些什么...
   ...
   SomeField   SomeType
}

// 正常,无指定结构体布局方式
type SomeType struct {
   a, b  int8
   x int32
   c, d int8
}

var x SomeType
var y HasHostLayout

var ap []*SomeType = []*SomeType{&x, &y.SomeField}
...

用法的重点:放在在结构体字段定义的第一个位置、使用 _ structs.HostLayout 进行初始化声明。以此即可指定结构体采用主机的内存布局方式。

总结

Go 的结构体内存布局是不少人研究和参考的对象之一,因为很多同学希望能够拿到最节省内存性能的方式。

但是实际上 Go 缺省的布局方式在不同的 OS 平台中,也有水土不服的。软件工程没有银弹。

本次 Go1.23 新增的 structs.HostLayout 有效的给 Go 程序员自定义结构体的内存布局打开了一个 “后门”,能够根据自己真实的主机平台情况进行定制化的结构体内存决策。

推荐阅读

关注和加煎鱼微信,

一手消息和知识,拉你进技术交流群👇

cde5bb75eeecb13564aea55edd72aa39.jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值