Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何将结构转换为Protobuf?_Go_Struct_Protocol Buffers_Proto - Fatal编程技术网

Go 如何将结构转换为Protobuf?

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

我正在做一个个人项目&第一次使用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     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
字段会很麻烦。