为什么不为结构比较指定特定的填充内容?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么不为结构比较指定特定的填充内容?相关的知识,希望对你有一定的参考价值。

摘自Dave Cheney的有关Go编译器(https://dave.cheney.net/2020/05/09/ensmallening-go-binaries-by-prohibiting-comparisons)生成的结构比较代码的文章:

存在填充以确保正确的字段对齐,并且尽管它确实占用了内存空间,但是这些填充字节的内容是未知的。您可能以为Go填充字节始终为零,但事实并非如此-填充字节的内容未定义。由于未将它们定义为始终为某个特定值,因此按位比较可能会返回false,因为九个填充字节分布在S的24个字节中[[[[以前定义的填充结构]可能不相同。

Go编译器通过生成所谓的相等函数来解决此问题。在这种情况下,S的相等函数知道如何通过只比较函数中的字段而跳过填充来比较类型S的两个值。

编辑:同一消息源指出,struct {int64, int64}是使用内存比较进行比较的,而struct {int64, int8}由于填充而需要自定义函数,从而扩大了生成的二进制数。

为什么Go编译器不通过定义填充字节的内容来解决此问题,因此它可以使用memcmp之类的东西进行比较?

编辑:对一个字而不是一个字节进行清零或比较是否有任何开销(例如:在上一个struct {int64, int8}示例中对零个字节而不是9进行清零和比较?]

答案
spec

结构值是可比较的,如果它们的所有字段都是可比较的。如果两个结构值对应的非空白字段相等,则它们相等。

换句话说,结构相等不是简单的逐字节比较。它是每个字段的比较,使用每个字段的可比性/相等性规则。

编辑:

即使填充被清零,仍然无法使用memcmp之类的东西直接比较许多结构。像字符串和接口之类的类型由于它们的基础类型表示而不能被[比较,即使它们在逻辑上是可比较的并且根据规范可以相等。要查看实际效果,请查看https://play.golang.org/p/lmu-THnWY3W

如果您想了解如何实现结构相等,请查看source code

以上是关于为什么不为结构比较指定特定的填充内容?的主要内容,如果未能解决你的问题,请参考以下文章

FirebaseRecyclerAdaptor 不会填充 recyclerview

opencv-python两张图片填充,指定区域替换其他图片

如何使用特定值填充ListView?

使用 json rereiver php mysql 在片段中填充列表视图

Excel自动填充到指定行

时间序列如何诊断个股 一个不为人知的炒股笔记曝光