У меня есть структура protobuf Data

В .proto:

message Data {
    uint64 ID = 1;
    uint32 GUID = 2;
}

В голанге

b, err := proto.Marshal(&pb.Data{})
if err != nil {
    panic(err)
}
fmt.Println(len(b))

У меня длина 0!

Как я могу сделать proto.Marshal всегда возвращать фиксированный размер независимо от того, что такое pb.Data?

Пс.

Pb.Data содержит только int64 и int32

0
xren 23 Окт 2018 в 16:02

2 ответа

Лучший ответ

Здесь есть две проблемы

1) protobuf использует кодировку varint для целых чисел, поэтому размер зависит от значения, см. эту ссылку

2) поля с нулевым значением не передаются по умолчанию, поэтому, поскольку два целых числа равны нулю, даже их идентификаторы полей не отправляются. На самом деле я не уверен, что есть возможность отправить нулевые значения, просматривая документы

Если вы установите для них обоих значение 1, у вас будет больше нуля байтов, но он все равно не будет фиксированной по длине, в зависимости от диапазона значений

Итак, нет реального способа принудительно установить фиксированный размер в сообщениях protobuf в целом

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

Cap'n Proto может иметь опцию для структур фиксированного размера, но они также обычно сжимают, что, опять же, создает сообщения переменной длины.

Если вы описываете проблему, которую пытаетесь решить, возможно, мы предложим другие альтернативы.

1
David Budworth 23 Окт 2018 в 17:35

Вы вызываете len() для байтового массива. Он подсчитает количество элементов в этом массиве и вернет его.

Если вы только что создали новый пустой объект-указатель protobuf, внутри которого ничего нет, маршалированный байтовый массив не будет содержать никаких данных - вот почему вы получаете 0.

Я совершенно не уверен, что вы хотите вернуть вместо этого. Не могли бы вы немного пояснить свой вопрос, указав, каким должен быть результат? Я могу лучше ответить на твой вопрос.

0
Henry Henderson 23 Окт 2018 в 13:31
52949803