我希望能够在Go中创建结构的可重复字节数组,因此我可以对它们进行散列,然后在某个时候验证该散列。
我目前正在按照这种简单的方法从具有以下结构的结构中创建字节数组:
[]byte(fmt.Sprintf("%v", struct))...)
这非常有效,直到我的结构体包含带有指针的嵌入式结构体,例如:
type testEmbeddedPointerStruct struct {
T *testSimpleStruct
}
在我的测试中,每次创建一个不同的字节数组,我认为可能是因为指针每次都更改内存中的地址?
即使结构包含指针,有没有一种创建可重复字节数组摘要的方法?
谢谢
...我认为可能是因为指针的内存中的地址发生了变化...
那是显而易见的候选人,是的。您选择了一种非常简单的编码,其中将指针字段编码为指针的十六进制表示形式,而不是在指针目标处找到的任何值。
即使结构包含指针,有没有一种创建可重复字节数组摘要的方法?
您可能需要更精确地定义“相同值的重复”对您意味着什么,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}
我们现在有两个不同的实体t1
和t2
,它们都“包含为一个值” {1 2}
。在Go中,t1
和t2
不同,因为它们的指针不同。换句话说,它们的价值是不同的。在提出的encoding中,t1
和t2
都编码相同,因此它们是same值。
这是指针发生的事情:底层数据可能是相同的,从某种意义上说是“相同的值”,但是保存这些值的对象的位置可能不同,因此,如果修改了一个对象,则其他不是。如果您通过使它们成为share pointed-to值的先编码后解码过程来运行此类对象,则您可能会放弃修改一个对象而不修改另一个对象或区分这些对象的能力。他们。
由于您可以选择编码方式,因此[[you可以完全确定您想要在此处进行的操作。但是您必须有目的地做出选择,而不仅仅是偶然。