登录
首页 >  Golang >  Go问答

为何Go语言中没有指定结构体比较时的填充内容?

来源:stackoverflow

时间:2024-03-07 23:36:27 386浏览 收藏

在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是Golang学习者,那么本文《为何Go语言中没有指定结构体比较时的填充内容?》就很适合你!本篇内容主要包括##content_title##,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

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

填充的存在是为了确保正确的字段对齐,虽然它确实占用了内存空间,但这些填充字节的内容是未知的。您可能会认为,对于 Go,填充字节始终为零,但事实证明并非如此 - 填充字节的内容根本没有定义。因为它们没有定义为始终为某个值,所以进行按位比较可能会返回 false,因为分布在 S 的 24 个字节中的 9 个字节的填充[先前定义的带填充的结构]可能不同。 Go 编译器通过生成所谓的相等函数来解决这个问题。在这种情况下,S 的相等函数知道如何通过仅比较函数中的字段同时跳过填充来比较两个 S 类型的值。

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

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

编辑:清零或比较一个字而不是一个字节是否有任何开销(例如:清零并比较 16 个字节而不是前面 struct {int64, int8} 示例中的 9 个字节)?


解决方案


来自spec

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

编辑:

即使填充为零,许多结构仍然无法使用 memcmp 之类的东西直接进行比较。像字符串和接口这样的类型由于其底层类型表示而无法在内存中进行比较,尽管它们在逻辑上是可比较的并且根据规范可以是相等的。要查看实际效果,请查看 https://play.golang.org/p/lmu-THnWY3W

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

今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>