首页 > 解决方案 > 创建包含指针的 Go 结构的可重复字节数组

问题描述

我希望能够在 Go 中创建可重复的结构字节数组,以便我可以对它们进行哈希处理,然后在某个时候验证该哈希值。

我目前正在按照这种简单的方法从结构中创建一个字节数组:

[]byte(fmt.Sprintf("%v", struct))...)

在我的结构包含一个带有指针的嵌入式结构之前,这非常有效,例如:

type testEmbeddedPointerStruct struct {
    T *testSimpleStruct
}

在我的测试中,这每次都会创建一个不同的字节数组,我认为这可能是因为指针每次都会改变内存中的地址?

即使结构包含指针,是否有办法创建可重复的字节数组摘要?

谢谢

标签: gostructencodinghashbyte

解决方案


...我认为这可能是因为指针在内存中的地址发生了变化...

那是显而易见的候选人,是的。您选择了一种非常简单的编码,其中指针字段被编码为指针的十六进制表示,而不是在指针目标处找到的任何值。

即使结构包含指针,是否有办法创建可重复的字节数组摘要?

您可能需要更准确地定义“相同值的重复”对您意味着什么,1但总的来说,这确实是一个编码问题。该encoding/gob包可能会在此处为您提供所需的编码,但请注意,与%v格式化不同,它仅对导出的结构字段进行编码保留各种名称。它具有“展平”任何指针数据的效果,但不适用于循环数据结构。

(您可以编写自己的更简单的编码器,在遇到指针时简单地跟随指针,否则像%v.)


1例如,假设您有:

type T struct {
    I int
    P *Sub
}
type Sub struct {
    J int
}
// ...
s2 := Sub{2}
s3 := Sub{3}
t1 := T{1, &s2}
t2 := T{1, &s3}

显然打印 t1 和 t2 (同时展平指针)会分别生成和的编码版本{1 2}{1 3}因此它们不是相同的值。但是,如果我们将s3自身更改为:

s3 := Sub{2}

我们现在有两个不同的实体t1t2,它们都“作为值包含” {1 2}。在 Go 中,t1t2是不同的,因为它们的指针不同。换句话说,他们的价值观是不同的。在提出的编码中,t1两者t2的编码相同,所以它们的值相同

这就是指针所发生的事情:底层数据可能是相同的——在某种意义上是“相同的值”——但持有这些值的对象可能在位置上不同,所以如果一个对象被修改,另一个对象是不是。如果您通过使这些对象共享指向值的编码后解码过程来运行此类对象,则您可能会放弃修改一个对象而不修改另一个对象或区分它们的能力。

由于您可以选择如何进行编码,因此可以准确地决定您希望在这里发生什么。但是你必须有目的地做出这个选择,而不是偶然。


推荐阅读