编码/ gob确定性? [英] Is encoding/gob deterministic?

查看:139
本文介绍了编码/ gob确定性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们可以期待两个Go对象x,y,使得x等于y(假设接口和映射,结构和数组没有任何技巧),gob_encode(x)和gob_encode(y)的输出将始终为相同?

解决方案

只要完成工作,您就不应该在乎。但是目前的 编码/ gob 实现是确定性。但是(继续阅读)!



因为:


自我描述。流中的每个数据项前都有一个类型的规范,用一小组预定义的类型表示。


意味着如果您第一次对类型的值进行编码,则会发送类型信息。如果您编码了另一个相同类型的值,那么类型描述将不会再次传输,只是参考其之前的规范。所以即使你编码两次相同的值,它会产生不同的字节序列,因为第一个将包含类型spec和值,第二个将只包含一个类型ref(例如类型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 ):

<$ p $ [23 c code] [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] sequence。



但是,如果您创建2个不同的 gob.Encoder s,然后按照相同的顺序编写相同的值,他们会产生确切的结果。



请注意,在前面的陈述中,相同的顺序也很重要。因为类型说明是在发送此类型的第一个值时发送的,所以按不同顺序发送不同类型的值也会按不同顺序发送类型说明,因此类型的参考/标识可能不同,这意味着当这样的类型被编码,不同类型的引用/ id将被使用/发送。



另外请注意,执行 gob

Can we expect for two Go objects x, y such that x is equal to y (assuming no trickiness with interfaces and maps, just structs and arrays) that the output of gob_encode(x) and gob_encode(y) will always be the same?

解决方案

You shouldn't really care as long as it "gets the job done". But current encoding/gob implementation is deterministic. But (continue reading)!

Since:

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.

This means if you encode a value of a type for the first time, type information will be sent. If you encode another value of the same type, the type description will not be transmitted again, just a reference to its previous spec. So even if you encode the same value twice, it will produce different byte sequences as the first will contain type spec and the value, the second will contain only a type ref (e.g. type id) and the value.

See this example:

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())

Output (try it on the 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]

As seen the first Encode() generates lots of bytes plus the value for our Int value being [5 255 130 1 2 0], the second and third calls add the same [5 255 130 1 2 0] sequence.

But if you create 2 different gob.Encoders and you write the same values in the same order, they will produce exact results.

Note that in the previous statement "same order" is also important. Because type specification is transmitted when first value of such type is sent, sending values of different types in different order will transmit type specs in different order too, and so the references/identifiers of the types may differ, which implies that when a value of such type is encoded, different type reference/id will be used/sent.

Also note that the implementation of the gob package may change from release to release. These changes will be backward compatible (they must explicitly state if for some reason they would make backward incompatible changes), but being backward compatible does not mean the output is the same. So different Go versions may produce different results (but all is decodeable with all compatible versions).

这篇关于编码/ gob确定性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆