gpt4 book ai didi

go - 编码/gob 是确定性的吗?

转载 作者:IT王子 更新时间:2023-10-29 01:26:01 26 4
gpt4 key购买 nike

我们能否期望两个 Go 对象 x, y 使得 x 等于 y(假设接口(interface)和映射没有技巧,只是结构和数组)gob_encode(x) 和 gob_encode(y) 的输出将始终是一样吗?

编辑(2018 年 6 月 8 日):

当涉及 map 时,gob 编码是非确定性。这是由于 map 的随机迭代顺序,导致它们的序列化顺序随机。

最佳答案

只要它“完成工作”,您就不必太在意。但电流encoding/gob实现是确定性的。但是(继续阅读)!

开始于:

A stream of gobs is self-describing. Each data item in the stream is preceded by a specification of its type, expressed in terms of a small set of predefined types.

这意味着如果您第一次对某个类型的值进行编码,则会发送类型信息。如果您对同一类型的另一个值进行编码,则不会再次传输类型描述,只是对其先前规范的引用。因此,即使您对同一个值进行两次编码,它也会产生不同的字节序列,因为第一个将包含类型规范和值,第二个将仅包含一个类型引用(例如类型 id)和值。

看这个例子:

type Int struct{ X int }

b := &bytes.Buffer{}
e := gob.NewEncoder(b)

e.Encode(Int{1})
fmt.Println(b.Bytes())

e.Encode(Int{1})
fmt.Println(b.Bytes())

e.Encode(Int{1})
fmt.Println(b.Bytes())

输出(在 Go Playground 上尝试):

[23 255 129 3 1 1 3 73 110 116 1 255 130 0 1 1 1 1 88 1 4 0 0 0 5 255 130 1 2 0]
[23 255 129 3 1 1 3 73 110 116 1 255 130 0 1 1 1 1 88 1 4 0 0 0 5 255 130 1 2 0 5 255 130 1 2 0]
[23 255 129 3 1 1 3 73 110 116 1 255 130 0 1 1 1 1 88 1 4 0 0 0 5 255 130 1 2 0 5 255 130 1 2 0 5 255 130 1 2 0]

正如所见,第一个 Encode() 生成大量字节加上我们的 Int 值为 [5 255 130 1 2 0],第二个和第三个调用添加相同的 [5 255 130 1 2 0] 序列。

但是如果你创建 2 个不同的 gob.Encoder s 并且您以相同的顺序写入相同的值,它们将产生准确的结果。

请注意,在前面的声明中“相同顺序”也很重要。因为类型规范是在发送这种类型的第一个值时传输的,所以以不同顺序发送不同类型的值也会以不同顺序传输类型规范,因此类型的引用/标识符可能不同,这意味着当值这样的类型被编码,将使用/发送不同的类型引用/id。

另请注意,gob 包的实现可能会因版本而异。这些更改将向后兼容(它们必须明确说明是否出于某种原因它们会进行向后不兼容的更改),但向后兼容并不意味着输出是相同的。所以不同的 Go 版本可能会产生不同的结果(但所有兼容版本都可以解码)。

关于go - 编码/gob 是确定性的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33228700/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com