英文:
How to set/get protobuf's extension field in Go?
问题
我是一名Go语言开发者。我们团队选择使用协议缓冲(protocol buffers)来转换数据。
我选择了这个protobuf包:https://github.com/golang/protobuf。
然而,这个包没有提供处理协议缓冲中的extensions
字段的方法。我只在由protoc生成的类文件中找到了以下代码:
var E_Height = &proto.ExtensionDesc{
ExtendedType: (*Person)(nil),
ExtensionType: (*int32)(nil),
Field: 110,
Name: "eg.Height",
Tag: "varint,110,opt",
}
func init() {
proto.RegisterExtension(E_Height)
}
那么,在Go语言中如何设置/获取extensions
字段呢?
英文:
I am a Go language developer. Our team chose to use protocol buffers to transform data.
I chose this protobuf package: https://github.com/golang/protobuf.
However, this package has no method to handle the extensions
field in a protocol buffer. I have only found this code in the class file generated by protoc:
<!-- language: go -->
var E_Height = &proto.ExtensionDesc{
ExtendedType: (*Person)(nil),
ExtensionType: (*int32)(nil),
Field: 110,
Name: "eg.Height",
Tag: "varint,110,opt",
}
func init() {
proto.RegisterExtension(E_Height)
}
So, how can I set/get the extensions
field in Go?
答案1
得分: 2
获取扩展...
yourExtendedEvent := &path_to_your_events.Person{}
err := proto.Unmarshal(yourBytes, yourExtendedEvent)
if err != nil {
// 处理错误情况
}
extendedEvent, extendedError := proto.GetExtension(
yourExtendedEvent,
path_to_your_events.E_Height,
)
...
设置扩展...
yourExtendedEvent := &path_to_your_events.Person{
Field1: proto.Uint64(1),
Field2: proto.String("foo"),
}
height := &path_to_your_events.Height {
Field1: proto.Int64(120),
}
err := proto.SetExtension(
yourExtendedEvent,
path_to_your_events.E_Height,
height,
)
if err != nil {
// 处理错误情况
}
编辑
实际上,如果我理解正确,你的扩展只是一个单独的字段(int32),所以我不知道你是否实际上有一个 Height
类型。如果没有的话,可能更像是这样的:
height := proto.Int32(120)
然后,你以相同的方式设置高度,将其作为单个字段而不是作为一个独立的 proto 类型。
这行代码
ExtensionType: (*int32)(nil),
让我觉得它将是一个单个字段,而我们的扩展看起来更像是
ExtensionType: (*SomeOtherType)(nil),
这是一个很好的资源
TestExtensionsRoundTrip
英文:
Getting the extension...
yourExtendedEvent := &path_to_your_events.Person{}
err := proto.Unmarshal(yourBytes, yourExtendedEvent)
if err != nil {
// handle error case
}
extendedEvent, extendedError := proto.GetExtension(
yourExtendedEvent,
path_to_your_events.E_Height,
)
...
Setting the extension...
yourExtendedEvent := &path_to_your_events.Person{
Field1: proto.Uint64(1),
Field2: proto.String("foo"),
}
height := &path_to_your_events.Height {
Field1: proto.Int64(120),
}
err := proto.SetExtension(
yourExtendedEvent,
path_to_your_events.E_Height,
height,
)
if err != nil {
// handle error case
}
EDIT
Actually, if I am reading it right, your extension is just a single field (an int32) so I don't know that you actually have a Height
type. If not, it might be more like
height := proto.Int32(120)
And then you set the same way with height as a single field rather than as a distinct proto type.
This line
ExtensionType: (*int32)(nil),
Makes me think it will be a single field, whereas our extensions look more like
ExtensionType: (*SomeOtherType)(nil),
This is a good resource
TestExtensionsRoundTrip
答案2
得分: 1
从:https://developers.google.com/protocol-buffers/docs/reference/go-generated#extensions
例如,给定以下定义:
extend Foo {
optional int32 singular_int32 = 1;
repeated bytes repeated_string = 2;
optional Bar repeated_message = 3;
}
可以通过以下方式访问扩展值:
m := &somepb.Foo{}
proto.SetExtension(m, extpb.E_SingularInt32, int32(1))
proto.SetExtension(m, extpb.E_RepeatedString, []string{"a", "b", "c"})
proto.SetExtension(m, extpb.E_RepeatedMessage, &extpb.Bar{})
v1 := proto.GetExtension(m, extpb.E_SingularInt32).(int32)
v2 := proto.GetExtension(m, extpb.E_RepeatedString).([][]byte)
v3 := proto.GetExtension(m, extpb.E_RepeatedMessage).(*extpb.Bar)
英文:
From: https://developers.google.com/protocol-buffers/docs/reference/go-generated#extensions
> For example, given the following definition:
>
>
> extend Foo {
> optional int32 singular_int32 = 1;
> repeated bytes repeated_string = 2;
> optional Bar repeated_message = 3;
> }
>
>
> Extension values may be accessed as:
>
>
> m := &somepb.Foo{}
> proto.SetExtension(m, extpb.E_SingularInt32, int32(1))
> proto.SetExtension(m, extpb.E_RepeatedString, []string{"a", "b", "c"})
> proto.SetExtension(m, extpb.E_RepeatedMessage, &extpb.Bar{})
>
> v1 := proto.GetExtension(m, extpb.E_SingularInt32).(int32)
> v2 := proto.GetExtension(m, extpb.E_RepeatedString).([][]byte)
> v3 := proto.GetExtension(m, extpb.E_RepeatedMessage).(*extpb.Bar)
>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论