В языке программирования Go для работы с протоколом буферизации сообщений protobuf используется пакет "github.com/golang/protobuf/proto". Для установки этого пакета вы можете выполнить команду:
go get github.com/golang/protobuf/proto
Для того чтобы сделать обязательным указание одного из двух полей в сообщении protobuf, вам нужно воспользоваться опциями "oneof" и "oneof" во время определения сообщения в файле .proto.
Допустим, у вас есть следующее определение сообщения в файле example.proto:
syntax = "proto3"; package example; message MyMessage { oneof data { int32 number = 1; string text = 2; } }
В этом определении мы объявляем "oneof data", в качестве вариантов которого указаны два поля: "number" с типом int32 и "text" с типом string.
Поле, которое будет задано в сообщении, будет сохранено, а значение другого поля будет сброшено.
Теперь, при генерации кода на Go из этого файла .proto, вы получите структуру с тегом "oneof". Например:
type MyMessage struct { Data *MyMessage_Number `protobuf:"bytes,1,oneof,data,1,opt,name=number"` // или // Data *MyMessage_Text `protobuf:"bytes,2,oneof,data,2,opt,name=text"` }
Такая структура данных позволяет вам работать только с одним из двух полей, но не обоими сразу.
Следующий пример кода показывает, как создавать и использовать сообщение, чтобы задать значение одного из двух полей:
package main import ( "fmt" "github.com/golang/protobuf/proto" "github.com/example/examplepb" ) func main() { message := &examplepb.MyMessage{ Data: &examplepb.MyMessage_Number{ Number: 42, }, } // Преобразование сообщения в бинарное представление data, err := proto.Marshal(message) if err != nil { fmt.Println("Ошибка при маршалинге:", err) return } // Декодирование бинарных данных в сообщение decodedMessage := &examplepb.MyMessage{} err = proto.Unmarshal(data, decodedMessage) if err != nil { fmt.Println("Ошибка при декодировании:", err) return } // Вывод значения одного из полей if decodedMessage.GetNumber() != 0 { fmt.Println("Значение number:", decodedMessage.GetNumber()) } else if decodedMessage.GetText() != "" { fmt.Println("Значение text:", decodedMessage.GetText()) } }
В этом примере мы создаем сообщение MyMessage с полем Number, устанавливаем значение 42 и затем преобразуем его в бинарную форму. Затем мы декодируем бинарные данные обратно в сообщение и выводим значение Number.