为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
人到中年有点甜 2023-07-04 16:45:15
我正在开发一个个人项目,并且是第一次使用 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 Pythonrecord := &pb.Record{        Size: 20,        Data: &(pb.Data{**kvData}), // Won't work}我尝试谷歌搜索,但找不到任何解释如何执行此操作的解决方案。请注意,我不仅仅是想解决这个特定的情况,我还想知道在结构和原型之间操作的推荐Go方式是什么(仅使用原型?)?
查看完整描述

3 回答

?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

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


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


XXX_NoUnkeyedLiteral         struct{} `json:"-"`

XXX_unrecognized             []byte   `json:"-"`

XXX_sizecache                int32    `json:"-"`

因此,您的struct和生成的字段具有不同的字段并且不相同,因此不可分配。


如果两个结构仅在标签上不同,则可以将其转换:


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手动创建一个新实例。


查看完整回答
反对 回复 2023-07-04
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

你能得到的最接近的是这样的:


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

}

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


编辑:如果Go 1.8之前的结构类型不完全相同(相同的标签等),则无法转换它们。更新的 Playground 链接到演示不匹配的标签将与go 1.8或稍后进行转换。


查看完整回答
反对 回复 2023-07-04
?
叮当猫咪

TA贡献1776条经验 获得超12个赞

您可以使用第三方库 gogofaster 从 .proto 文件生成 go 代码。

gogofaster 是一个更快的生成工具,它不包含结构中的额外字段 (XXX_*),从而使转换更简单(因为结构现在将是相同的)。

查看完整回答
反对 回复 2023-07-04
  • 3 回答
  • 0 关注
  • 348 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信