1 回答

TA貢獻1777條經驗 獲得超3個贊
典型的方法是使用以下命令將協議編譯protoc
為 Go 代碼:
protoc?main.proto?--go_out=.
這將生成main.pb.go
,其類型稱為Address
:
var?addr?Address err?:=?proto.Unmarshal(bytes,?&addr)
如果由于某種原因這是不可能的(例如,您必須使用描述符動態地執行此操作),那么還有其他選擇。(但情況要復雜得多。)
使用
protoc
生成的描述符。您可以protoc
導出到描述符文件(通過-o
標志)。如果這是用于 RPC,請讓服務器使用服務器反射;然后,您可以使用github.com/jhump/protoreflect/grpcreflect包下載服務器的描述符(大概由 生成protoc
)。如果您必須以編程方式創建描述符,而不是使用
protoc
,我建議使用github.com/jhump/protoreflect/desc/builder包來構造它(而不是嘗試手動創建原始原型)。例如,您的原始原型是不夠的,因為它們沒有parent?FileDescriptorProto
,它是任何描述符層次結構的根。該構建器包可以為您處理類似的細節(例如,如果需要,它將合成父文件描述符)。
無論如何,您想要的描述符是 a?desc.Descriptor
(來自github.com/jhump/protoreflect/desc包)。上面的提示(使用其他 protoreflect 子包)將返回desc.Descriptor
實例。如果您只有原始描述符原型(如示例代碼中所示),您需要首先使用desc#CreateFileDescriptor*descriptor.FileDescriptorProto
函數將其轉換為 a?。*desc.FileDescriptor
如果您正在使用protoc
及其-o
選項來創建描述符集文件(也不要忘記標志),您可以使用desc#CreateFileDescriptorFromSet--include_imports
函數加載它并將其轉換為描述符集文件。這是一個例子:*desc.FileDescriptor
bytes, err := ioutil.ReadFile("protoset-from-protoc")
if err != nil {
? panic(err)
}
var fileSet descriptor.FileDescriptorSet
if err := proto.Unmarshal(bytes, &fileSet); err != nil {
? panic(err)
}
fd, err := desc.CreateFileDescriptorFromSet(&fileSet)
if err != nil {
? panic(err)
}
// Now you have a *desc.FileDescriptor in `fd`
一旦有了正確的描述符,您就可以創建一個*dynamic.Message。然后,您可以使用該proto#Unmarshal函數或使用動態消息的Unmarshal方法對其進行解組。
- 1 回答
- 0 關注
- 268 瀏覽
添加回答
舉報