我们先看来下下面的代码:

对于上面定义的这两个结构体,都有a、b、c三个定义完全一样的字段,只是在定义结构体的时候字段顺序不一样而已,那么两种写法有什么影响吗?

对于不了解golang内部结构的同学来说,感觉着没有什么区别的,只是一个书写顺序不同而已,但对于go编译器来说,则有着很大的区别,特别是在不同架构上(32位/64位)的编译器,在一定程度上对内存的使用大小和执行效率有着一定的不同。这里就引出了golang语言中一个重要的概念:内存对齐(alignment guarantee)

Go白皮书只对以下种类的类型的尺寸进行了规定:

但对其它种类的类型的尺寸没有做最初明确规定,如果想获取其他类型所对应的标准编译器的类型尺寸,可以参考:

标准编译器(和gccgo编译器)将确保一个类型的尺寸为此类型的对齐保证的倍数。

为了满足上一节中规定的地址对齐保证要求,Go编译器可能会在结构体的相邻字段之间填充一些字节。 这使得一个结构体类型的尺寸并非等于它的各个字段类型尺寸的简单相加之和。

下面是一个展示了一些字节是如何填充到一个结构体中的例子。 首先,从上面的描述中,我们已得知(对于标准编译器来说):

int8int16int64T1T2int64T1T2
T1T2
T1的内存对齐


T2的内存对齐

这里推荐一个网站:

,可以用来查看结构的内存布局,Type size的值越小越好,这样就可以对结构体进行一些内存大小优化了。