Go 如何将结构转换为Protobuf?
我正在做一个个人项目&第一次使用Go。我使用structs对数据进行操作并将数据存储在文件中,我使用proto作为编码器 在项目中,我的原型定义如下所示Go 如何将结构转换为Protobuf?,go,struct,protocol-buffers,proto,Go,Struct,Protocol Buffers,Proto,我正在做一个个人项目&第一次使用Go。我使用structs对数据进行操作并将数据存储在文件中,我使用proto作为编码器 在项目中,我的原型定义如下所示 message Data { string key = 1; string value = 2; } message Record { int64 size = 1; Data data = 2; } type KVData struct { Key string Value
message Data {
string key = 1;
string value = 2;
}
message Record {
int64 size = 1;
Data data = 2;
}
type KVData struct {
Key string
Value string
}
我的结构是这样的
message Data {
string key = 1;
string value = 2;
}
message Record {
int64 size = 1;
Data data = 2;
}
type KVData struct {
Key string
Value string
}
目前,这就是我创建原型数据的方式
kvData := KVData{Key: "name", Value: "A"}
record := &pb.Record{
Size: 20,
Data: &pb.Data{Key: "name", Value: "A"},
}
我正在寻找一种实现这一点的方法:
record := &pb.Record{
Size: 20,
Data: &((pb.Data)kvData), // Won't work
}
// or like Python
record := &pb.Record{
Size: 20,
Data: &(pb.Data{**kvData}), // Won't work
}
我试着用谷歌搜索,但找不到任何解释如何做到这一点的方法
请注意,我不仅仅是想解决这个具体问题,我还想知道在结构和proto之间操作的推荐方式是什么(仅使用proto?)您可以得到的最接近的方式是:
pbData := pb.Data(kvData) // convert kvData struct to pb.Data struct
record := &pb.Record{
Size: 20,
Data: &pbData,
}
注意:您不能像这样将这两个步骤结合起来:
record := &pb.Record{
Size: 20,
Data: &(pb.Data(kvData)), // BROKEN: can't get address of a return-value
}
您可以在此处进行更多实验:
编辑:如果预结构类型不完全相同,则无法转换它们(相同的标记等)。更新的用于演示不匹配标记的操场链接将使用
go 1.8
或更高版本进行转换。您不能,至少在go 1.12.7中不能
Go的Protobuf编译器为从消息生成的每个结构添加3个额外字段:
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
因此,您的struct
和生成的struct具有不同的字段,并且根据不相同,因此不相同
如果两个结构仅在标记上不同,则可以:
您必须手动创建一个新的
struct
实例。您可以使用gogofaster这一第三方库从.proto文件生成go代码
gogofaster是一种更快的生成工具,它不包括结构中的额外字段(XXX_*),从而简化转换(因为结构现在将完全相同)
您可以在此处了解更多信息:
Uber的Prototool也支持gogofaster
希望这有帮助。
kvData.(pb.Data)
获取此无效类型断言:kvData.(pb.Data)(左侧为非接口类型kvData)
很抱歉弄错了,pb.Data(kvData)
现在,此操作失败,无法将kvData(kvData类型)转换为pb.Data类型。
仅供参考。。。消息记录
的protobuf字段号可能应该是1
和2
——而不是3
和4
。消息记录
独立于消息数据
——因此它们的字段号是独立的。如果为了向后兼容而设置字段值,只需要从后面的数字开始。我认为Pawel关于proto的回答是正确的。Proto添加了一些额外的字段。但你的回答确实触及了我问题的一部分,而且很有帮助。谢谢啊!!问题不包括您使用的protoc版本。是,使用syntax=“proto3”代码>仅为琐碎的类型转换而包含额外生成的XXX
字段会很麻烦。