如何将结构转换/转换为Protobuf?

时间:2019-07-16 19:49:23

标签: go struct protocol-buffers proto

我正在做一个个人项目,并且是第一次使用Go。我正在使用结构来操作数据并将数据存储在文件中,我正在使用proto作为编码器。

在项目中,我的原型定义看起来像这样

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?)之间进行操作的推荐Go方法是什么?

3 个答案:

答案 0 :(得分:1)

您可以获得的最接近的东西是:

onStartCommand(Intent, int, int)

注意:您不能将这两个步骤结合在一起,例如:

pbData := pb.Data(kvData) // convert kvData struct to pb.Data struct

record := &pb.Record{
        Size: 20,
        Data: &pbData,
}

您可以在这里进行更多实验:https://play.golang.org/p/2AhWi0Khe4l

编辑:如果go 1.8之前的结构类型不完全相同(相同的标记等),则无法转换。更新的游乐场链接到演示不匹配的标记将转换为{{1} }或更高版本。

答案 1 :(得分:1)

您不能,至少在Go 1.12.7中不能。

Go的Protobuf编译器向从消息生成的每个结构添加3个额外的字段:

XXX_NoUnkeyedLiteral         struct{} `json:"-"`
XXX_unrecognized             []byte   `json:"-"`
XXX_sizecache                int32    `json:"-"`

因此,您的struct和生成的字段具有不同的字段,并且每个字段都不相同,因此不是assignable

如果两个结构仅在标记中不同,则可以convert it

type Person struct {
    Name    string
    Address *struct {
        Street string
        City   string
    }
}

var data *struct {
    Name    string `json:"name"`
    Address *struct {
        Street string `json:"street"`
        City   string `json:"city"`
    } `json:"address"`
}

var person = (*Person)(data)  // ignoring tags, the underlying types are identical

您必须手动创建一个新的struct实例。

答案 2 :(得分:0)

您可以使用gogofaster(这是一个第三方库)从您的.proto文件生成go代码。

gogofaster是一种生成速度更快的工具,它在结构中不包含多余的字段(XXX_ *),从而使转换更加简单(因为结构现在相同)。

您可以在此处了解更多信息:https://github.com/gogo/protobuf

Uber的Prototool也支持gogofaster。

希望这会有所帮助。