How to set/get protobuf's extension field in Go?

huangapple go评论71阅读模式
英文:

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 = &amp;proto.ExtensionDesc{
	ExtendedType:  (*Person)(nil),
	ExtensionType: (*int32)(nil),
	Field:         110,
	Name:          &quot;eg.Height&quot;,
	Tag:           &quot;varint,110,opt&quot;,
}

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 := &amp;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 := &amp;path_to_your_events.Person{
    Field1: proto.Uint64(1),
    Field2: proto.String(&quot;foo&quot;),
}

height := &amp;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:
>
>
&gt; extend Foo {
&gt; optional int32 singular_int32 = 1;
&gt; repeated bytes repeated_string = 2;
&gt; optional Bar repeated_message = 3;
&gt; }
&gt;

>
> Extension values may be accessed as:
>
>
&gt; m := &amp;somepb.Foo{}
&gt; proto.SetExtension(m, extpb.E_SingularInt32, int32(1))
&gt; proto.SetExtension(m, extpb.E_RepeatedString, []string{&quot;a&quot;, &quot;b&quot;, &quot;c&quot;})
&gt; proto.SetExtension(m, extpb.E_RepeatedMessage, &amp;extpb.Bar{})
&gt;
&gt; v1 := proto.GetExtension(m, extpb.E_SingularInt32).(int32)
&gt; v2 := proto.GetExtension(m, extpb.E_RepeatedString).([][]byte)
&gt; v3 := proto.GetExtension(m, extpb.E_RepeatedMessage).(*extpb.Bar)
&gt;

huangapple
  • 本文由 发表于 2015年3月3日 00:52:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/28815214.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定