Arrays Go中protobuf数组元素的范围
我在.proto文件中定义了一个Protobuf结构:Arrays Go中protobuf数组元素的范围,arrays,go,protocol-buffers,proto,Arrays,Go,Protocol Buffers,Proto,我在.proto文件中定义了一个Protobuf结构: message Msg{ message SubMsg { string SubVariable1 = 1; int32 SubVariable2 = 2; ... } string Variable1 = 1; repeated SubMsg Variable2 = 2; ... } 在使用JSON API中的数据时,我使用包将数据拉入此结构,如下所示: Response, err := Cl
message Msg{
message SubMsg {
string SubVariable1 = 1;
int32 SubVariable2 = 2;
...
}
string Variable1 = 1;
repeated SubMsg Variable2 = 2;
...
}
在使用JSON API中的数据时,我使用包将数据拉入此结构,如下所示:
Response, err := Client.Do(Request)
if err != nil {
log.Error(err)
}
DataByte, err := ioutil.ReadAll(Response.Body)
if err != nil {
log.Error(err)
}
DataProto := Msg{}
err = protojson.Unmarshal(DataByte, &DataProto)
if err != nil {
log.Error(err)
}
我想能够做的是在Variable2的元素范围内,能够使用protoreflect API访问子变量,为此我尝试了以下两种方法:
Array := DataProto.GetVariable2()
for i := range Array {
Element := Array[i]
}
而且:
DataProto.GetVariable2().ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
…
return true})
其中第一个失败,并显示错误消息:
cannot range over DataProto.GetVariable2() (type *SubMsg)
尽管事实是DataProto.GetVariable2()
返回类型为[]*Msg\u SubMsg
的变量
第二个失败的原因是:
DataProto.GetVariable2.ProtoReflect undefined (type []*SubMsg has no field or method ProtoReflect)
这表明DataProto.GetVariable2()
确实返回了一个数组,这与我在第一种方法中返回的错误中所建议的不同。这对我来说很有意义,因为protoreflect API只允许对已定义的消息调用此方法,而不允许对这些消息的数组进行调用。因此,必须有另一种方法访问这些数组的元素,才能使用protoreflect API(到目前为止,我在web上还没有找到并回答这个问题)
有人能帮我理解这些看似矛盾的错误信息吗?有人自己成功地迭代了Protobuf数组吗
提前感谢。您需要将
数组
变量视为列表
,这意味着您不能像第二次尝试那样使用范围()。不过很接近。下面是迭代和检查嵌套消息的功能示例:
import (
"testing"
"google.golang.org/protobuf/reflect/protoreflect"
)
func TestVariable2(t *testing.T) {
pb := &Msg{
Variable2: []*Msg_SubMsg{
{
SubVariable1: "string",
SubVariable2: 1,
},
},
}
pbreflect := pb.ProtoReflect()
fd := pbreflect.Descriptor().Fields().ByJSONName("Variable2")
if !fd.IsList() {
t.Fatal("expected a list")
}
l := pbreflect.Get(fd).List()
for i := 0; i < l.Len(); i++ {
// should test that we are now inspecting a message type
li := l.Get(i).Message()
li.Range(func(lifd protoreflect.FieldDescriptor, liv protoreflect.Value) bool {
t.Logf("%v: %v", lifd.Name(), liv)
return true
})
}
}
进口(
“测试”
“google.golang.org/protobuf/reflect/protoreflect”
)
func TestVariable2(t*testing.t){
pb:=&Msg{
变量2:[]*Msg\u SubMsg{
{
子变量1:“字符串”,
子变量2:1,
},
},
}
pbreflect:=pb.ProtoReflect()
fd:=pbreflect.Descriptor().Fields().ByJSONName(“Variable2”)
if!fd.IsList(){
t、 致命(“需要列表”)
}
l:=pbreflect.Get(fd.List())
对于i:=0;i
使用go test-v./…
运行,如果您想查看输出是否有令人信服的理由使用protoreflect
包?Range
方法用于迭代消息结构的所有字段-它不适用于碰巧是(重复的
)片段的单个字段。我可能误解了protoreflect Range函数给表带来的内容。考虑到我正在努力迭代一个数组,我认为它将是我的灵丹妙药,因为它提供了访问protoreflect.Value的能力,而调用DataProto.Variable2则不会。即使在没有protoreflect包的情况下接近它(试图覆盖DataProto.Variable2),也会出现同样的错误。您知道我可以迭代未知长度的protobuf数组的方法吗?您似乎在用代码做其他事情。请附上一份。至少,展示一些可以运行的东西,包括生成的protobuf代码。