2015-10-20 2 views
3

Можно ли ожидать для двух объектов Go, x, y таких, что x равно y (при условии, что нет никаких обманчивости с интерфейсами и картами, просто структурами и массивами), что вывод gob_encode (x) и gob_encode (y) всегда будет одна и та же?Является ли кодирование/gob детерминированным?

ответ

5

Вы не должны волноваться, пока он «выполняет свою работу». Но текущая реализация encoding/gob детерминирована. Но (продолжайте читать)!

С:

Поток капель стекломассы является самоописываемыми. Каждому элементу данных в потоке предшествует спецификация его типа, выраженная в терминах небольшого набора предопределенных типов.

Это означает, что если вы впервые кодируете значение типа, введите информацию, которая будет отправлена. Если вы кодируете другое значение того же типа, описание типа не будет передаваться снова, просто ссылка на его предыдущую спецификацию. Поэтому, даже если вы дважды закодируете одно и то же значение, он будет генерировать разные байтовые последовательности, поскольку первый будет содержать спецификацию типа и значение, а второй будет содержать только тип ref (например, идентификатор типа) и значение.

Смотрите этот пример:

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 (попробовать его на 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 и вы будете писать те же значения в том же порядке, они будут давать точные результаты.

Обратите внимание, что в предыдущем заявлении также имеет значение «тот же порядок». Поскольку спецификация типа передается при отправке первого значения такого типа, отправка значений разных типов в другом порядке также будет передавать спецификации типов в другом порядке, поэтому ссылки/идентификаторы типов могут отличаться, что означает, что когда значение такой тип кодируется, будет использоваться/отправлен другой тип reference/id.

Также обратите внимание, что реализация пакета gob может измениться с момента выпуска до выпуска. Эти изменения будут обратно совместимы (они должны явно указывать, если по какой-то причине они сделают обратные несовместимые изменения), но совместимость с обратной совместимостью не означает, что вывод одинаков. Поэтому разные версии Go могут давать разные результаты (но все они декодируются со всеми совместимыми версиями).

Смежные вопросы